summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoren[m] <Break@Ocean>2013-09-09 14:53:27 +0200
committerCoren[m] <Break@Ocean>2013-09-09 14:53:27 +0200
commit55214aa041f2cc0305d290ff7dfd9e3e2f5e0bde (patch)
treef8a632cc3b559989d945a6f021ade3d1a919eabf
parent29d777ef67bc964229722db073a2abdd1eb737b6 (diff)
network.*:
- IP4: changed in_addr_t to struct in_addr for compatibility reasons - IP6: added - IPAny: added - addr_resolve_or_parse_ip(): converts a string into an IPAny
-rw-r--r--toxcore/network.c178
-rw-r--r--toxcore/network.h22
2 files changed, 198 insertions, 2 deletions
diff --git a/toxcore/network.c b/toxcore/network.c
index 622a4b17..f504401e 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -234,3 +234,181 @@ void kill_networking(Networking_Core *net)
234 free(net); 234 free(net);
235 return; 235 return;
236} 236}
237
238/*
239 * addr_parse_ip
240 * directly parses the input into an IP structure
241 * tries IPv4 first, then IPv6
242 *
243 * input
244 * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
245 *
246 * output
247 * IP: family and the value is set on success
248 *
249 * returns 1 on success, 0 on failure
250 */
251
252int addr_parse_ip(const char *address, IPAny *to)
253{
254 struct in_addr addr4;
255 if (1 == inet_pton(AF_INET, address, &addr4))
256 {
257 to->family = AF_INET;
258 to->ip4.in_addr = addr4;
259 return 1;
260 };
261
262 struct in6_addr addr6;
263 if (1 == inet_pton(AF_INET6, address, &addr6))
264 {
265 to->family = AF_INET6;
266 to->ip6 = addr6;
267 return 1;
268 };
269
270 return 0;
271};
272
273/*
274 * addr_resolve():
275 * uses getaddrinfo to resolve an address into an IP address
276 * uses the first IPv4/IPv6 addresses returned by getaddrinfo
277 *
278 * input
279 * address: a hostname (or something parseable to an IP address)
280 * ip: ip.family MUST be initialized, either set to a specific IP version
281 * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
282 * IP versions are acceptable
283 *
284 * returns in ip a valid IPAny (v4/v6),
285 * prefers v6 if ip.family was AF_UNSPEC and both available
286 * returns 0 on failure
287 */
288
289int addr_resolve(const char *address, IPAny *ip)
290{
291 struct addrinfo *server = NULL;
292 struct addrinfo *walker = NULL;
293 struct addrinfo hints;
294 int rc;
295
296 memset(&hints, 0, sizeof(hints));
297 hints.ai_family = ip->family;
298 hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
299
300#ifdef __WIN32__
301 WSADATA wsa_data;
302
303 /* CLEANUP: really not the best place to put this */
304 rc = WSAStartup(MAKEWORD(2, 2), &wsa_data);
305
306 if (rc != 0) {
307 return 0;
308 }
309
310#endif
311
312 rc = getaddrinfo(address, NULL, &hints, &server);
313 // Lookup failed.
314 if (rc != 0) {
315#ifdef __WIN32__
316 WSACleanup();
317#endif
318 return 0;
319 }
320
321 IP4 ip4;
322 memset(&ip4, 0, sizeof(ip4));
323 IP6 ip6;
324 memset(&ip6, 0, sizeof(ip6));
325
326 walker = server;
327 while (walker && (rc != 3))
328 {
329 if (ip->family != AF_UNSPEC)
330 {
331 if (walker->ai_family == ip->family) {
332 if (ip->family == AF_INET)
333 {
334 if (walker->ai_addrlen == sizeof(struct sockaddr_in))
335 {
336 struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
337 ip->ip4.in_addr = addr->sin_addr;
338 rc = 3;
339 }
340 }
341 else if (ip->family == AF_INET6)
342 {
343 if (walker->ai_addrlen == sizeof(struct sockaddr_in6))
344 {
345 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
346 ip->ip6 = addr->sin6_addr;
347 rc = 3;
348 }
349 }
350 }
351 }
352 else
353 {
354 if (walker->ai_family == AF_INET)
355 {
356 if (walker->ai_addrlen == sizeof(struct sockaddr_in))
357 {
358 struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
359 ip4.in_addr = addr->sin_addr;
360 rc |= 1;
361 }
362 }
363 else if (walker->ai_family == AF_INET6)
364 {
365 if (walker->ai_addrlen == sizeof(struct sockaddr_in6))
366 {
367 struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
368 ip6 = addr->sin6_addr;
369 rc |= 2;
370 }
371 }
372 }
373
374 walker = walker->ai_next;
375 }
376
377 if (ip->family == AF_UNSPEC)
378 {
379 if (rc & 2)
380 {
381 ip->family = AF_INET6;
382 ip->ip6 = ip6;
383 } else if (rc & 1)
384 {
385 ip->family = AF_INET;
386 ip->ip4 = ip4;
387 }
388 else
389 rc = 0;
390 }
391
392
393 freeaddrinfo(server);
394#ifdef __WIN32__
395 WSACleanup();
396#endif
397 return rc;
398}
399
400/*
401 * addr_resolve_or_parse_ip
402 * resolves string into an IP address
403 *
404 * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6)
405 * returns 1 on success, 0 on failure
406 */
407int addr_resolve_or_parse_ip(const char *address, IPAny *to)
408{
409 if (!addr_resolve(address, to))
410 if (!addr_parse_ip(address, to))
411 return 0;
412
413 return 1;
414};
diff --git a/toxcore/network.h b/toxcore/network.h
index 9991c4a4..2a0b5560 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -86,9 +86,19 @@ typedef union {
86 uint8_t uint8[4]; 86 uint8_t uint8[4];
87 uint16_t uint16[2]; 87 uint16_t uint16[2];
88 uint32_t uint32; 88 uint32_t uint32;
89 in_addr_t in_addr; 89 struct in_addr in_addr;
90} IP4; 90} IP4;
91 91
92typedef struct in6_addr IP6;
93
94typedef struct {
95 sa_family_t family;
96 union {
97 IP4 ip4;
98 IP6 ip6;
99 };
100} IPAny;
101
92typedef union { 102typedef union {
93 struct { 103 struct {
94 IP4 ip; 104 IP4 ip;
@@ -109,6 +119,15 @@ typedef struct {
109#endif 119#endif
110} ADDR; 120} ADDR;
111 121
122/*
123 * addr_resolve_or_parse_ip
124 * resolves string into an IP address
125 *
126 * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6)
127 * returns 1 on success, 0 on failure
128 */
129int addr_resolve_or_parse_ip(const char *address, IPAny *to);
130
112/* Function to receive data, ip and port of sender is put into ip_port. 131/* Function to receive data, ip and port of sender is put into ip_port.
113 * Packet data is put into data. 132 * Packet data is put into data.
114 * Packet length is put into length. 133 * Packet length is put into length.
@@ -161,5 +180,4 @@ Networking_Core *new_networking(IP4 ip, uint16_t port);
161/* Function to cleanup networking stuff (doesn't do much right now). */ 180/* Function to cleanup networking stuff (doesn't do much right now). */
162void kill_networking(Networking_Core *net); 181void kill_networking(Networking_Core *net);
163 182
164
165#endif 183#endif