OLD | NEW |
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 #if defined(FLETCH_TARGET_OS_MACOS) | 5 #if defined(FLETCH_TARGET_OS_MACOS) |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 pthread_t tid; | 59 pthread_t tid; |
60 result = pthread_create(&tid, &attr, ThreadFunction, ref); | 60 result = pthread_create(&tid, &attr, ThreadFunction, ref); |
61 if (result != 0) Fatal("Error from pthread_create"); | 61 if (result != 0) Fatal("Error from pthread_create"); |
62 | 62 |
63 result = pthread_attr_destroy(&attr); | 63 result = pthread_attr_destroy(&attr); |
64 if (result != 0) Fatal("Error from pthread_attr_destroy"); | 64 if (result != 0) Fatal("Error from pthread_attr_destroy"); |
65 | 65 |
66 return 0; | 66 return 0; |
67 } | 67 } |
68 | 68 |
69 // Callback for results initiated by calling DNSServiceGetAddrInfo. | 69 |
70 static void GetAddrInfoCallback(DNSServiceRef ref, | 70 // Callback for results initiated by calling DNSServiceQueryRecord. |
| 71 static void QueryRecordCallback(DNSServiceRef ref, |
71 DNSServiceFlags flags, | 72 DNSServiceFlags flags, |
72 uint32_t interfaceIndex, | 73 uint32_t interfaceIndex, |
73 DNSServiceErrorType errorCode, | 74 DNSServiceErrorType errorCode, |
74 const char *hostname, | 75 const char *fullname, |
75 const struct sockaddr *address, | 76 uint16_t rrtype, |
| 77 uint16_t rrclass, |
| 78 uint16_t rdlen, |
| 79 const void* rdata, |
76 uint32_t ttl, | 80 uint32_t ttl, |
77 void *context) { | 81 void *context) { |
78 if (address->sa_family == AF_INET) { | 82 if (rrclass != kDNSServiceClass_IN) return; |
79 const struct sockaddr_in* address_in = (const struct sockaddr_in*)address; | |
80 const uint8_t* addr = | |
81 reinterpret_cast<const uint8_t*>(&address_in->sin_addr.s_addr); | |
82 | 83 |
83 struct Context* ctx = reinterpret_cast<struct Context*>(context); | 84 struct Context* ctx = reinterpret_cast<struct Context*>(context); |
84 | 85 |
85 // Build the response message. | 86 if (rrtype != kDNSServiceType_A && |
86 Dart_CObject cobject_hostname; | 87 rrtype != kDNSServiceType_SRV && |
87 cobject_hostname.type = Dart_CObject_kString; | 88 rrtype != kDNSServiceType_PTR) { |
88 cobject_hostname.value.as_string = const_cast<char*>(hostname); | 89 // Ignore unsupported types. |
89 Dart_CObject cobject_address; | 90 return; |
90 cobject_address.type = Dart_CObject_kTypedData; | 91 } |
91 cobject_address.value.as_typed_data.length = 4; | |
92 cobject_address.value.as_typed_data.type = Dart_TypedData_kUint8; | |
93 cobject_address.value.as_typed_data.values = const_cast<uint8_t*>(addr); | |
94 Dart_CObject cobject_result; | |
95 cobject_result.type = Dart_CObject_kArray; | |
96 Dart_CObject* result_array[] = {&cobject_hostname, &cobject_address}; | |
97 cobject_result.value.as_array.length = 2; | |
98 cobject_result.value.as_array.values = result_array; | |
99 Dart_PostCObject(ctx->port, &cobject_result); | |
100 | 92 |
101 // Result received, free allocated data and stop lookup. | 93 // Build the response message. |
102 free(ctx); | 94 Dart_CObject cobject_fullname; |
103 DNSServiceRefDeallocate(ref); | 95 cobject_fullname.type = Dart_CObject_kString; |
104 } | 96 cobject_fullname.value.as_string = const_cast<char*>(fullname); |
| 97 Dart_CObject cobject_type; |
| 98 cobject_type.type = Dart_CObject_kInt32; |
| 99 cobject_type.value.as_int32 = rrtype; |
| 100 Dart_CObject cobject_ttl; |
| 101 cobject_ttl.type = Dart_CObject_kInt32; |
| 102 cobject_ttl.value.as_int32 = ttl; |
| 103 Dart_CObject cobject_data; |
| 104 cobject_data.type = Dart_CObject_kTypedData; |
| 105 cobject_data.value.as_typed_data.length = rdlen; |
| 106 cobject_data.value.as_typed_data.type = Dart_TypedData_kUint8; |
| 107 cobject_data.value.as_typed_data.values = |
| 108 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(rdata)); |
| 109 Dart_CObject cobject_result; |
| 110 cobject_result.type = Dart_CObject_kArray; |
| 111 Dart_CObject* result_array[] = |
| 112 {&cobject_fullname, &cobject_type, &cobject_ttl, &cobject_data}; |
| 113 cobject_result.value.as_array.length = 4; |
| 114 cobject_result.value.as_array.values = result_array; |
| 115 Dart_PostCObject(ctx->port, &cobject_result); |
| 116 |
| 117 // Result received, free allocated data and stop lookup. |
| 118 free(ctx); |
| 119 DNSServiceRefDeallocate(ref); |
105 } | 120 } |
106 | 121 |
107 // Lookup request from Dart. | 122 // Lookup request from Dart. |
108 void HandleLookup(Dart_Port port_id, char* hostname) { | 123 void HandleLookup(Dart_Port port_id, int type, char* fullname) { |
109 DNSServiceRef ref; | 124 DNSServiceRef ref; |
110 DNSServiceErrorType result; | 125 DNSServiceErrorType result; |
111 struct Context* context = | 126 struct Context* context = |
112 reinterpret_cast<struct Context*>(malloc(sizeof(struct Context))); | 127 reinterpret_cast<struct Context*>(malloc(sizeof(struct Context))); |
113 context->port = port_id; | 128 context->port = port_id; |
114 result = DNSServiceGetAddrInfo(&ref, | 129 result = DNSServiceQueryRecord(&ref, |
115 0, | 130 0, |
116 0, | 131 0, |
117 kDNSServiceProtocol_IPv4, | 132 fullname, |
118 hostname, | 133 type, |
119 &GetAddrInfoCallback, | 134 kDNSServiceClass_IN, |
| 135 &QueryRecordCallback, |
120 context); | 136 context); |
121 if (result != kDNSServiceErr_NoError) { | 137 if (result != kDNSServiceErr_NoError) { |
122 fprintf(stderr, "Error from DNSServiceProcessResult: %d\n", result); | 138 fprintf(stderr, "Error from DNSServiceQueryRecord: %d\n", result); |
123 } else { | 139 } else { |
124 // Start a thread for retreiving the results. | 140 // Start a thread for retreiving the results. |
125 // TODO(sgjesse): Add a timeout for killing the thread if there | 141 // TODO(sgjesse): Add a timeout for killing the thread if there |
126 // are no responses. | 142 // are no responses. |
127 StartThread(ref); | 143 StartThread(ref); |
128 } | 144 } |
129 } | 145 } |
130 | 146 |
131 #endif | 147 #endif |
OLD | NEW |