diff options
Diffstat (limited to 'src/nat/nat_api_stun.c')
-rw-r--r-- | src/nat/nat_api_stun.c | 156 |
1 files changed, 79 insertions, 77 deletions
diff --git a/src/nat/nat_api_stun.c b/src/nat/nat_api_stun.c index 0f8694867..461dae1f5 100644 --- a/src/nat/nat_api_stun.c +++ b/src/nat/nat_api_stun.c | |||
@@ -43,9 +43,9 @@ | |||
43 | 43 | ||
44 | #include "nat_stun.h" | 44 | #include "nat_stun.h" |
45 | 45 | ||
46 | #define LOG(kind, ...) GNUNET_log_from(kind, "stun", __VA_ARGS__) | 46 | #define LOG(kind, ...) GNUNET_log_from (kind, "stun", __VA_ARGS__) |
47 | 47 | ||
48 | #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 15) | 48 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) |
49 | 49 | ||
50 | 50 | ||
51 | /** | 51 | /** |
@@ -53,7 +53,8 @@ | |||
53 | * the request prior to the timeout or successful execution. Also | 53 | * the request prior to the timeout or successful execution. Also |
54 | * used to track our internal state for the request. | 54 | * used to track our internal state for the request. |
55 | */ | 55 | */ |
56 | struct GNUNET_NAT_STUN_Handle { | 56 | struct GNUNET_NAT_STUN_Handle |
57 | { | ||
57 | /** | 58 | /** |
58 | * Handle to a pending DNS lookup request. | 59 | * Handle to a pending DNS lookup request. |
59 | */ | 60 | */ |
@@ -99,11 +100,12 @@ struct GNUNET_NAT_STUN_Handle { | |||
99 | * @return message in a STUN compatible format | 100 | * @return message in a STUN compatible format |
100 | */ | 101 | */ |
101 | static int | 102 | static int |
102 | encode_message(enum StunClasses msg_class, | 103 | encode_message (enum StunClasses msg_class, |
103 | enum StunMethods method) | 104 | enum StunMethods method) |
104 | { | 105 | { |
105 | return ((msg_class & 1) << 4) | ((msg_class & 2) << 7) | | 106 | return ((msg_class & 1) << 4) | ((msg_class & 2) << 7) |
106 | (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800) << 2); | 107 | | (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800) |
108 | << 2); | ||
107 | } | 109 | } |
108 | 110 | ||
109 | 111 | ||
@@ -113,12 +115,12 @@ encode_message(enum StunClasses msg_class, | |||
113 | * @param req, stun header to be filled | 115 | * @param req, stun header to be filled |
114 | */ | 116 | */ |
115 | static void | 117 | static void |
116 | generate_request_id(struct stun_header *req) | 118 | generate_request_id (struct stun_header *req) |
117 | { | 119 | { |
118 | req->magic = htonl(STUN_MAGIC_COOKIE); | 120 | req->magic = htonl (STUN_MAGIC_COOKIE); |
119 | for (unsigned int x = 0; x < 3; x++) | 121 | for (unsigned int x = 0; x < 3; x++) |
120 | req->id.id[x] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, | 122 | req->id.id[x] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, |
121 | UINT32_MAX); | 123 | UINT32_MAX); |
122 | } | 124 | } |
123 | 125 | ||
124 | 126 | ||
@@ -130,67 +132,67 @@ generate_request_id(struct stun_header *req) | |||
130 | * @param addrlen length of @a addr | 132 | * @param addrlen length of @a addr |
131 | */ | 133 | */ |
132 | static void | 134 | static void |
133 | stun_dns_callback(void *cls, | 135 | stun_dns_callback (void *cls, |
134 | const struct sockaddr *addr, | 136 | const struct sockaddr *addr, |
135 | socklen_t addrlen) | 137 | socklen_t addrlen) |
136 | { | 138 | { |
137 | struct GNUNET_NAT_STUN_Handle *rh = cls; | 139 | struct GNUNET_NAT_STUN_Handle *rh = cls; |
138 | struct stun_header req; | 140 | struct stun_header req; |
139 | struct sockaddr_in server; | 141 | struct sockaddr_in server; |
140 | 142 | ||
141 | if (NULL == addr) | 143 | if (NULL == addr) |
144 | { | ||
145 | rh->dns_active = NULL; | ||
146 | if (GNUNET_NO == rh->dns_success) | ||
147 | { | ||
148 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
149 | "Error resolving host %s\n", | ||
150 | rh->stun_server); | ||
151 | rh->cb (rh->cb_cls, | ||
152 | GNUNET_NAT_ERROR_NOT_ONLINE); | ||
153 | } | ||
154 | else if (GNUNET_SYSERR == rh->dns_success) | ||
142 | { | 155 | { |
143 | rh->dns_active = NULL; | 156 | rh->cb (rh->cb_cls, |
144 | if (GNUNET_NO == rh->dns_success) | 157 | GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR); |
145 | { | ||
146 | LOG(GNUNET_ERROR_TYPE_INFO, | ||
147 | "Error resolving host %s\n", | ||
148 | rh->stun_server); | ||
149 | rh->cb(rh->cb_cls, | ||
150 | GNUNET_NAT_ERROR_NOT_ONLINE); | ||
151 | } | ||
152 | else if (GNUNET_SYSERR == rh->dns_success) | ||
153 | { | ||
154 | rh->cb(rh->cb_cls, | ||
155 | GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR); | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | rh->cb(rh->cb_cls, | ||
160 | GNUNET_NAT_ERROR_SUCCESS); | ||
161 | } | ||
162 | GNUNET_NAT_stun_make_request_cancel(rh); | ||
163 | return; | ||
164 | } | 158 | } |
159 | else | ||
160 | { | ||
161 | rh->cb (rh->cb_cls, | ||
162 | GNUNET_NAT_ERROR_SUCCESS); | ||
163 | } | ||
164 | GNUNET_NAT_stun_make_request_cancel (rh); | ||
165 | return; | ||
166 | } | ||
165 | 167 | ||
166 | rh->dns_success = GNUNET_YES; | 168 | rh->dns_success = GNUNET_YES; |
167 | memset(&server, 0, sizeof(server)); | 169 | memset (&server, 0, sizeof(server)); |
168 | server.sin_family = AF_INET; | 170 | server.sin_family = AF_INET; |
169 | server.sin_addr = ((struct sockaddr_in *)addr)->sin_addr; | 171 | server.sin_addr = ((struct sockaddr_in *) addr)->sin_addr; |
170 | server.sin_port = htons(rh->stun_port); | 172 | server.sin_port = htons (rh->stun_port); |
171 | #if HAVE_SOCKADDR_IN_SIN_LEN | 173 | #if HAVE_SOCKADDR_IN_SIN_LEN |
172 | server.sin_len = (u_char)sizeof(struct sockaddr_in); | 174 | server.sin_len = (u_char) sizeof(struct sockaddr_in); |
173 | #endif | 175 | #endif |
174 | 176 | ||
175 | /* Craft the simplest possible STUN packet. A request binding */ | 177 | /* Craft the simplest possible STUN packet. A request binding */ |
176 | generate_request_id(&req); | 178 | generate_request_id (&req); |
177 | req.msglen = htons(0); | 179 | req.msglen = htons (0); |
178 | req.msgtype = htons(encode_message(STUN_REQUEST, | 180 | req.msgtype = htons (encode_message (STUN_REQUEST, |
179 | STUN_BINDING)); | 181 | STUN_BINDING)); |
180 | 182 | ||
181 | /* Send the packet */ | 183 | /* Send the packet */ |
182 | if (-1 == | 184 | if (-1 == |
183 | GNUNET_NETWORK_socket_sendto(rh->sock, | 185 | GNUNET_NETWORK_socket_sendto (rh->sock, |
184 | &req, | 186 | &req, |
185 | sizeof(req), | 187 | sizeof(req), |
186 | (const struct sockaddr *)&server, | 188 | (const struct sockaddr *) &server, |
187 | sizeof(server))) | 189 | sizeof(server))) |
188 | { | 190 | { |
189 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, | 191 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, |
190 | "sendto"); | 192 | "sendto"); |
191 | rh->dns_success = GNUNET_SYSERR; | 193 | rh->dns_success = GNUNET_SYSERR; |
192 | return; | 194 | return; |
193 | } | 195 | } |
194 | } | 196 | } |
195 | 197 | ||
196 | 198 | ||
@@ -206,31 +208,31 @@ stun_dns_callback(void *cls, | |||
206 | * @return NULL on error | 208 | * @return NULL on error |
207 | */ | 209 | */ |
208 | struct GNUNET_NAT_STUN_Handle * | 210 | struct GNUNET_NAT_STUN_Handle * |
209 | GNUNET_NAT_stun_make_request(const char *server, | 211 | GNUNET_NAT_stun_make_request (const char *server, |
210 | uint16_t port, | 212 | uint16_t port, |
211 | struct GNUNET_NETWORK_Handle *sock, | 213 | struct GNUNET_NETWORK_Handle *sock, |
212 | GNUNET_NAT_TestCallback cb, | 214 | GNUNET_NAT_TestCallback cb, |
213 | void *cb_cls) | 215 | void *cb_cls) |
214 | { | 216 | { |
215 | struct GNUNET_NAT_STUN_Handle *rh; | 217 | struct GNUNET_NAT_STUN_Handle *rh; |
216 | 218 | ||
217 | rh = GNUNET_new(struct GNUNET_NAT_STUN_Handle); | 219 | rh = GNUNET_new (struct GNUNET_NAT_STUN_Handle); |
218 | rh->sock = sock; | 220 | rh->sock = sock; |
219 | rh->cb = cb; | 221 | rh->cb = cb; |
220 | rh->cb_cls = cb_cls; | 222 | rh->cb_cls = cb_cls; |
221 | rh->stun_server = GNUNET_strdup(server); | 223 | rh->stun_server = GNUNET_strdup (server); |
222 | rh->stun_port = port; | 224 | rh->stun_port = port; |
223 | rh->dns_success = GNUNET_NO; | 225 | rh->dns_success = GNUNET_NO; |
224 | rh->dns_active = GNUNET_RESOLVER_ip_get(rh->stun_server, | 226 | rh->dns_active = GNUNET_RESOLVER_ip_get (rh->stun_server, |
225 | AF_INET, | 227 | AF_INET, |
226 | TIMEOUT, | 228 | TIMEOUT, |
227 | &stun_dns_callback, | 229 | &stun_dns_callback, |
228 | rh); | 230 | rh); |
229 | if (NULL == rh->dns_active) | 231 | if (NULL == rh->dns_active) |
230 | { | 232 | { |
231 | GNUNET_NAT_stun_make_request_cancel(rh); | 233 | GNUNET_NAT_stun_make_request_cancel (rh); |
232 | return NULL; | 234 | return NULL; |
233 | } | 235 | } |
234 | return rh; | 236 | return rh; |
235 | } | 237 | } |
236 | 238 | ||
@@ -242,15 +244,15 @@ GNUNET_NAT_stun_make_request(const char *server, | |||
242 | * @param rh request to cancel | 244 | * @param rh request to cancel |
243 | */ | 245 | */ |
244 | void | 246 | void |
245 | GNUNET_NAT_stun_make_request_cancel(struct GNUNET_NAT_STUN_Handle *rh) | 247 | GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh) |
246 | { | 248 | { |
247 | if (NULL != rh->dns_active) | 249 | if (NULL != rh->dns_active) |
248 | { | 250 | { |
249 | GNUNET_RESOLVER_request_cancel(rh->dns_active); | 251 | GNUNET_RESOLVER_request_cancel (rh->dns_active); |
250 | rh->dns_active = NULL; | 252 | rh->dns_active = NULL; |
251 | } | 253 | } |
252 | GNUNET_free(rh->stun_server); | 254 | GNUNET_free (rh->stun_server); |
253 | GNUNET_free(rh); | 255 | GNUNET_free (rh); |
254 | } | 256 | } |
255 | 257 | ||
256 | 258 | ||