diff options
Diffstat (limited to 'src/nat/nat_api_stun.c')
-rw-r--r-- | src/nat/nat_api_stun.c | 155 |
1 files changed, 76 insertions, 79 deletions
diff --git a/src/nat/nat_api_stun.c b/src/nat/nat_api_stun.c index a0931a06f..0f8694867 100644 --- a/src/nat/nat_api_stun.c +++ b/src/nat/nat_api_stun.c | |||
@@ -11,12 +11,12 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * This code provides some support for doing STUN transactions. | 21 | * This code provides some support for doing STUN transactions. |
22 | * We send simplest possible packet ia REQUEST with BIND to a STUN server. | 22 | * We send simplest possible packet ia REQUEST with BIND to a STUN server. |
@@ -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,9 +53,7 @@ | |||
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 | { | ||
58 | |||
59 | /** | 57 | /** |
60 | * Handle to a pending DNS lookup request. | 58 | * Handle to a pending DNS lookup request. |
61 | */ | 59 | */ |
@@ -90,7 +88,6 @@ struct GNUNET_NAT_STUN_Handle | |||
90 | * STUN port | 88 | * STUN port |
91 | */ | 89 | */ |
92 | uint16_t stun_port; | 90 | uint16_t stun_port; |
93 | |||
94 | }; | 91 | }; |
95 | 92 | ||
96 | 93 | ||
@@ -102,11 +99,11 @@ struct GNUNET_NAT_STUN_Handle | |||
102 | * @return message in a STUN compatible format | 99 | * @return message in a STUN compatible format |
103 | */ | 100 | */ |
104 | static int | 101 | static int |
105 | encode_message (enum StunClasses msg_class, | 102 | encode_message(enum StunClasses msg_class, |
106 | enum StunMethods method) | 103 | enum StunMethods method) |
107 | { | 104 | { |
108 | return ((msg_class & 1) << 4) | ((msg_class & 2) << 7) | | 105 | return ((msg_class & 1) << 4) | ((msg_class & 2) << 7) | |
109 | (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800) << 2); | 106 | (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800) << 2); |
110 | } | 107 | } |
111 | 108 | ||
112 | 109 | ||
@@ -116,12 +113,12 @@ encode_message (enum StunClasses msg_class, | |||
116 | * @param req, stun header to be filled | 113 | * @param req, stun header to be filled |
117 | */ | 114 | */ |
118 | static void | 115 | static void |
119 | generate_request_id (struct stun_header *req) | 116 | generate_request_id(struct stun_header *req) |
120 | { | 117 | { |
121 | req->magic = htonl(STUN_MAGIC_COOKIE); | 118 | req->magic = htonl(STUN_MAGIC_COOKIE); |
122 | for (unsigned int x = 0; x < 3; x++) | 119 | for (unsigned int x = 0; x < 3; x++) |
123 | req->id.id[x] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | 120 | req->id.id[x] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, |
124 | UINT32_MAX); | 121 | UINT32_MAX); |
125 | } | 122 | } |
126 | 123 | ||
127 | 124 | ||
@@ -133,67 +130,67 @@ generate_request_id (struct stun_header *req) | |||
133 | * @param addrlen length of @a addr | 130 | * @param addrlen length of @a addr |
134 | */ | 131 | */ |
135 | static void | 132 | static void |
136 | stun_dns_callback (void *cls, | 133 | stun_dns_callback(void *cls, |
137 | const struct sockaddr *addr, | 134 | const struct sockaddr *addr, |
138 | socklen_t addrlen) | 135 | socklen_t addrlen) |
139 | { | 136 | { |
140 | struct GNUNET_NAT_STUN_Handle *rh = cls; | 137 | struct GNUNET_NAT_STUN_Handle *rh = cls; |
141 | struct stun_header req; | 138 | struct stun_header req; |
142 | struct sockaddr_in server; | 139 | struct sockaddr_in server; |
143 | 140 | ||
144 | if (NULL == addr) | 141 | if (NULL == addr) |
145 | { | ||
146 | rh->dns_active = NULL; | ||
147 | if (GNUNET_NO == rh->dns_success) | ||
148 | { | ||
149 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
150 | "Error resolving host %s\n", | ||
151 | rh->stun_server); | ||
152 | rh->cb (rh->cb_cls, | ||
153 | GNUNET_NAT_ERROR_NOT_ONLINE); | ||
154 | } | ||
155 | else if (GNUNET_SYSERR == rh->dns_success) | ||
156 | { | 142 | { |
157 | rh->cb (rh->cb_cls, | 143 | rh->dns_active = NULL; |
158 | GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR); | 144 | if (GNUNET_NO == rh->dns_success) |
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; | ||
159 | } | 164 | } |
160 | else | ||
161 | { | ||
162 | rh->cb (rh->cb_cls, | ||
163 | GNUNET_NAT_ERROR_SUCCESS); | ||
164 | } | ||
165 | GNUNET_NAT_stun_make_request_cancel (rh); | ||
166 | return; | ||
167 | } | ||
168 | 165 | ||
169 | rh->dns_success = GNUNET_YES; | 166 | rh->dns_success = GNUNET_YES; |
170 | memset (&server, 0, sizeof(server)); | 167 | memset(&server, 0, sizeof(server)); |
171 | server.sin_family = AF_INET; | 168 | server.sin_family = AF_INET; |
172 | server.sin_addr = ((struct sockaddr_in *)addr)->sin_addr; | 169 | server.sin_addr = ((struct sockaddr_in *)addr)->sin_addr; |
173 | server.sin_port = htons (rh->stun_port); | 170 | server.sin_port = htons(rh->stun_port); |
174 | #if HAVE_SOCKADDR_IN_SIN_LEN | 171 | #if HAVE_SOCKADDR_IN_SIN_LEN |
175 | server.sin_len = (u_char) sizeof (struct sockaddr_in); | 172 | server.sin_len = (u_char)sizeof(struct sockaddr_in); |
176 | #endif | 173 | #endif |
177 | 174 | ||
178 | /* Craft the simplest possible STUN packet. A request binding */ | 175 | /* Craft the simplest possible STUN packet. A request binding */ |
179 | generate_request_id (&req); | 176 | generate_request_id(&req); |
180 | req.msglen = htons (0); | 177 | req.msglen = htons(0); |
181 | req.msgtype = htons (encode_message (STUN_REQUEST, | 178 | req.msgtype = htons(encode_message(STUN_REQUEST, |
182 | STUN_BINDING)); | 179 | STUN_BINDING)); |
183 | 180 | ||
184 | /* Send the packet */ | 181 | /* Send the packet */ |
185 | if (-1 == | 182 | if (-1 == |
186 | GNUNET_NETWORK_socket_sendto (rh->sock, | 183 | GNUNET_NETWORK_socket_sendto(rh->sock, |
187 | &req, | 184 | &req, |
188 | sizeof (req), | 185 | sizeof(req), |
189 | (const struct sockaddr *) &server, | 186 | (const struct sockaddr *)&server, |
190 | sizeof (server))) | 187 | sizeof(server))) |
191 | { | 188 | { |
192 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, | 189 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, |
193 | "sendto"); | 190 | "sendto"); |
194 | rh->dns_success = GNUNET_SYSERR; | 191 | rh->dns_success = GNUNET_SYSERR; |
195 | return; | 192 | return; |
196 | } | 193 | } |
197 | } | 194 | } |
198 | 195 | ||
199 | 196 | ||
@@ -209,31 +206,31 @@ stun_dns_callback (void *cls, | |||
209 | * @return NULL on error | 206 | * @return NULL on error |
210 | */ | 207 | */ |
211 | struct GNUNET_NAT_STUN_Handle * | 208 | struct GNUNET_NAT_STUN_Handle * |
212 | GNUNET_NAT_stun_make_request (const char *server, | 209 | GNUNET_NAT_stun_make_request(const char *server, |
213 | uint16_t port, | 210 | uint16_t port, |
214 | struct GNUNET_NETWORK_Handle *sock, | 211 | struct GNUNET_NETWORK_Handle *sock, |
215 | GNUNET_NAT_TestCallback cb, | 212 | GNUNET_NAT_TestCallback cb, |
216 | void *cb_cls) | 213 | void *cb_cls) |
217 | { | 214 | { |
218 | struct GNUNET_NAT_STUN_Handle *rh; | 215 | struct GNUNET_NAT_STUN_Handle *rh; |
219 | 216 | ||
220 | rh = GNUNET_new (struct GNUNET_NAT_STUN_Handle); | 217 | rh = GNUNET_new(struct GNUNET_NAT_STUN_Handle); |
221 | rh->sock = sock; | 218 | rh->sock = sock; |
222 | rh->cb = cb; | 219 | rh->cb = cb; |
223 | rh->cb_cls = cb_cls; | 220 | rh->cb_cls = cb_cls; |
224 | rh->stun_server = GNUNET_strdup (server); | 221 | rh->stun_server = GNUNET_strdup(server); |
225 | rh->stun_port = port; | 222 | rh->stun_port = port; |
226 | rh->dns_success = GNUNET_NO; | 223 | rh->dns_success = GNUNET_NO; |
227 | rh->dns_active = GNUNET_RESOLVER_ip_get (rh->stun_server, | 224 | rh->dns_active = GNUNET_RESOLVER_ip_get(rh->stun_server, |
228 | AF_INET, | 225 | AF_INET, |
229 | TIMEOUT, | 226 | TIMEOUT, |
230 | &stun_dns_callback, | 227 | &stun_dns_callback, |
231 | rh); | 228 | rh); |
232 | if (NULL == rh->dns_active) | 229 | if (NULL == rh->dns_active) |
233 | { | 230 | { |
234 | GNUNET_NAT_stun_make_request_cancel (rh); | 231 | GNUNET_NAT_stun_make_request_cancel(rh); |
235 | return NULL; | 232 | return NULL; |
236 | } | 233 | } |
237 | return rh; | 234 | return rh; |
238 | } | 235 | } |
239 | 236 | ||
@@ -245,15 +242,15 @@ GNUNET_NAT_stun_make_request (const char *server, | |||
245 | * @param rh request to cancel | 242 | * @param rh request to cancel |
246 | */ | 243 | */ |
247 | void | 244 | void |
248 | GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh) | 245 | GNUNET_NAT_stun_make_request_cancel(struct GNUNET_NAT_STUN_Handle *rh) |
249 | { | 246 | { |
250 | if (NULL != rh->dns_active) | 247 | if (NULL != rh->dns_active) |
251 | { | 248 | { |
252 | GNUNET_RESOLVER_request_cancel (rh->dns_active); | 249 | GNUNET_RESOLVER_request_cancel(rh->dns_active); |
253 | rh->dns_active = NULL; | 250 | rh->dns_active = NULL; |
254 | } | 251 | } |
255 | GNUNET_free (rh->stun_server); | 252 | GNUNET_free(rh->stun_server); |
256 | GNUNET_free (rh); | 253 | GNUNET_free(rh); |
257 | } | 254 | } |
258 | 255 | ||
259 | 256 | ||