summaryrefslogtreecommitdiff
path: root/toxcore/LAN_discovery.c
diff options
context:
space:
mode:
authorCoren[m] <Break@Ocean>2013-10-20 16:56:12 +0200
committerCoren[m] <Break@Ocean>2013-10-20 16:56:12 +0200
commita0f08839bd134f3f964a6cccf1243cd42f15d4e5 (patch)
treea313feee4c0d2a251cb460b9afe3766ca2422d5f /toxcore/LAN_discovery.c
parent8abad7bc822a548d4f6e73203e8d4f640c1217ae (diff)
Main: Eliminate TOX_ENABLE_IPV6 (then always on), CLIENT_ONETOONE_IP (then always off).
Additionally (besides cleanups): network.h/tox.h: - WIN32: fix a strange sa_family_t definition - WIN32: define EWOULDBLOCK to WSAEWOULDBLOCK - WIN32: kill macro for an existing function (IN6_ADDR_EQUAL) network.c: - use EWOULDBLOCK instead of EAGAIN (same value, but EWOULDBLOCK is more "popular") - new_networking(): only try to enable IPv4-in-IPv6 if it's not already enabled per default - inet_ntop()/inet_pton(): WIN32: remove partial initializers in favor of a simple memset() - ip_equal(): WIN32: use an existing function - logging: networking_wait_execute(): only dump result if not timeout - logging: loglogdata(): kill an unused variable LAN_discovery.c: - send_broadcasts(): re-enabled, can only support IPv4 by principle, split into fetch_broadcast_info() (to fetch the addresses once) and send_broadcasts() (actual sending) DHT.c: - DHT_load_state_callback(): enclosed a fprintf(stderr, ...) into #ifdef DEBUG Lossless_UDP.c: - change_handshake(): harden against strange sa_family_t definitions Messenger.c: - logging: fix ID to string conversion util.c: - logging: eliminate a signed-warning
Diffstat (limited to 'toxcore/LAN_discovery.c')
-rw-r--r--toxcore/LAN_discovery.c122
1 files changed, 60 insertions, 62 deletions
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index 1e4fa125..26366d0f 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -30,60 +30,83 @@
30#define MAX_INTERFACES 16 30#define MAX_INTERFACES 16
31 31
32#ifdef __linux 32#ifdef __linux
33#ifndef TOX_ENABLE_IPV6 33
34/* Send packet to all broadcast addresses 34static int broadcast_count = -1;
35 * 35static IP_Port broadcast_ip_port[MAX_INTERFACES];
36 * return higher than 0 on success. 36
37 * return 0 on error. 37static void fetch_broadcast_info(uint16_t port)
38 *
39 * TODO: Make this work with IPv6 and remove the #ifndef TOX_ENABLE_IPV6.
40 */
41static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t *data, uint16_t length)
42{ 38{
43 /* Not sure how many platforms this will run on, 39 /* Not sure how many platforms this will run on,
44 * so it's wrapped in __linux for now. 40 * so it's wrapped in __linux for now.
41 * Definitely won't work like this on Windows...
45 */ 42 */
46 struct sockaddr_in *sock_holder = NULL; 43 broadcast_count = 0;
47 struct ifreq i_faces[MAX_INTERFACES]; 44 sock_t sock = 0;
48 struct ifconf ifconf; 45 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
49 int count = 0; 46 return;
50 int sock = 0;
51 int i = 0;
52 47
53 /* Configure ifconf for the ioctl call. */ 48 /* Configure ifconf for the ioctl call. */
54 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 49 struct ifreq i_faces[MAX_INTERFACES];
55 return 1;
56 }
57
58 memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES); 50 memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES);
59 51
52 struct ifconf ifconf;
60 ifconf.ifc_buf = (char *)i_faces; 53 ifconf.ifc_buf = (char *)i_faces;
61 ifconf.ifc_len = sizeof(i_faces); 54 ifconf.ifc_len = sizeof(i_faces);
62 count = ifconf.ifc_len / sizeof(struct ifreq);
63 55
64 if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) { 56 if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
65 return 1; 57 close(sock);
58 return;
66 } 59 }
67 60
61 /* ifconf.ifc_len is set by the ioctl() to the actual length used;
62 * on usage of the complete array the call should be repeated with
63 * a larger array, not done (640kB and 16 interfaces shall be
64 * enough, for everybody!)
65 */
66 int i, count = ifconf.ifc_len / sizeof(struct ifreq);
68 for (i = 0; i < count; i++) { 67 for (i = 0; i < count; i++) {
69 if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { 68 /* there are interfaces with are incapable of broadcast */
70 return 1; 69 if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0)
71 } 70 continue;
72 71
73 /* Just to clarify where we're getting the values from. */ 72 /* moot check: only AF_INET returned (backwards compat.) */
74 sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr; 73 if (i_faces[i].ifr_broadaddr.sa_family != AF_INET)
75 74 continue;
76 if (sock_holder != NULL) { 75
77 IP_Port ip_port = {{{{sock_holder->sin_addr.s_addr}}, port, 0}}; 76 struct sockaddr_in *sock4 = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
78 sendpacket(net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); 77 IP_Port *ip_port = &broadcast_ip_port[broadcast_count];
79 } 78 ip_port->ip.family = AF_INET;
79 ip_port->ip.ip4.in_addr = sock4->sin_addr;
80 ip_port->port = port;
81 broadcast_count++;
80 } 82 }
81 83
82 close(sock); 84 close(sock);
83 return 0;
84} 85}
85#endif 86
86#endif 87/* Send packet to all IPv4 broadcast addresses
88 *
89 * return 1 if sent to at least one broadcast target.
90 * return 0 on failure to find any valid broadcast target.
91 */
92static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t *data, uint16_t length)
93{
94 /* fetch only once? on every packet? every X seconds?
95 * old: every packet, new: once */
96 if (broadcast_count < 0)
97 fetch_broadcast_info(port);
98
99 if (!broadcast_count)
100 return 0;
101
102 int i;
103
104 for(i = 0; i < broadcast_count; i++)
105 sendpacket(net, broadcast_ip_port[i], data, 1 + crypto_box_PUBLICKEYBYTES);
106
107 return 1;
108}
109#endif /* __linux */
87 110
88/* Return the broadcast ip. */ 111/* Return the broadcast ip. */
89static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) 112static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
@@ -91,8 +114,6 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
91 IP ip; 114 IP ip;
92 ip_reset(&ip); 115 ip_reset(&ip);
93 116
94#ifdef TOX_ENABLE_IPV6
95
96 if (family_socket == AF_INET6) { 117 if (family_socket == AF_INET6) {
97 if (family_broadcast == AF_INET6) { 118 if (family_broadcast == AF_INET6) {
98 ip.family = AF_INET6; 119 ip.family = AF_INET6;
@@ -116,14 +137,6 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
116 } 137 }
117 } 138 }
118 139
119#else
120
121 if (family_socket == AF_INET)
122 if (family_broadcast == AF_INET)
123 ip.uint32 = INADDR_BROADCAST;
124
125#endif
126
127 return ip; 140 return ip;
128} 141}
129 142
@@ -132,13 +145,8 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
132 */ 145 */
133int LAN_ip(IP ip) 146int LAN_ip(IP ip)
134{ 147{
135#ifdef TOX_ENABLE_IPV6
136
137 if (ip.family == AF_INET) { 148 if (ip.family == AF_INET) {
138 IP4 ip4 = ip.ip4; 149 IP4 ip4 = ip.ip4;
139#else
140 IP4 ip4 = ip;
141#endif
142 150
143 /* Loopback. */ 151 /* Loopback. */
144 if (ip4.uint8[0] == 127) 152 if (ip4.uint8[0] == 127)
@@ -161,9 +169,8 @@ int LAN_ip(IP ip)
161 && ip4.uint8[2] != 255) 169 && ip4.uint8[2] != 255)
162 return 0; 170 return 0;
163 171
164#ifdef TOX_ENABLE_IPV6 172 } else if (ip.family == AF_INET6) {
165 } else if (ip.family == AF_INET6) 173
166 {
167 /* autogenerated for each interface: FE80::* (up to FEBF::*) 174 /* autogenerated for each interface: FE80::* (up to FEBF::*)
168 FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ 175 FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
169 if (((ip.ip6.uint8[0] == 0xFF) && (ip.ip6.uint8[1] < 3) && (ip.ip6.uint8[15] == 1)) || 176 if (((ip.ip6.uint8[0] == 0xFF) && (ip.ip6.uint8[1] < 3) && (ip.ip6.uint8[15] == 1)) ||
@@ -179,8 +186,6 @@ int LAN_ip(IP ip)
179 } 186 }
180 } 187 }
181 188
182#endif
183
184 return -1; 189 return -1;
185} 190}
186 191
@@ -206,16 +211,12 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
206 memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES); 211 memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
207 212
208#ifdef __linux 213#ifdef __linux
209#ifndef TOX_ENABLE_IPV6
210 send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); 214 send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
211#endif 215#endif
212#endif
213 int res = -1; 216 int res = -1;
214 IP_Port ip_port; 217 IP_Port ip_port;
215 ip_port.port = port; 218 ip_port.port = port;
216 219
217#ifdef TOX_ENABLE_IPV6
218
219 /* IPv6 multicast */ 220 /* IPv6 multicast */
220 if (c->lossless_udp->net->family == AF_INET6) { 221 if (c->lossless_udp->net->family == AF_INET6) {
221 ip_port.ip = broadcast_ip(AF_INET6, AF_INET6); 222 ip_port.ip = broadcast_ip(AF_INET6, AF_INET6);
@@ -227,9 +228,6 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
227 228
228 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */ 229 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */
229 ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET); 230 ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET);
230#else
231 ip_port.ip = broadcast_ip(AF_INET, AF_INET);
232#endif
233 231
234 if (ip_isset(&ip_port.ip)) 232 if (ip_isset(&ip_port.ip))
235 if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES)) 233 if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES))