1 /* GNet - Networking library
2  * Copyright (C) 2000-2003  David Helder
3  * Copyright (C) 2000-2003  Andrew Lanoix
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA  02111-1307, USA.
19  */
20 
21 #include "gnet-private.h"
22 #include "udp.h"
23 
24 #define GNET_UDP_SOCKET_TYPE(s) (((GUdpSocket*)(s))->type)
25 #define GNET_IS_UDP_SOCKET(s)   ((s) && (GNET_UDP_SOCKET_TYPE(s) == GNET_UDP_SOCKET_TYPE_COOKIE \
26                                       || GNET_UDP_SOCKET_TYPE(s) == GNET_MCAST_SOCKET_TYPE_COOKIE))
27 
28 /**
29  *  gnet_udp_socket_new
30  *
31  *  Creates a #GUdpSocket bound to all interfaces and an arbitrary
32  *  port.
33  *
34  *  Returns: a new #GUdpSocket; NULL on error.
35  *
36  **/
37 GUdpSocket*
gnet_udp_socket_new(void)38 gnet_udp_socket_new (void)
39 {
40   return gnet_udp_socket_new_full (NULL, 0);
41 }
42 
43 
44 /**
45  *  gnet_udp_socket_new_with_port:
46  *  @port: port to bind to (0 for an arbitrary port)
47  *
48  *  Creates a #GUdpSocket bound to all interfaces and port @port.  If
49  *  @port is 0, an arbitrary port will be used.
50  *
51  *  Returns: a new #GUdpSocket; NULL on error.
52  *
53  **/
54 GUdpSocket*
gnet_udp_socket_new_with_port(gint port)55 gnet_udp_socket_new_with_port (gint port)
56 {
57   return gnet_udp_socket_new_full (NULL, port);
58 }
59 
60 
61 /**
62  *  gnet_udp_socket_new_full
63  *  @iface: interface to bind to (NULL for all interfaces)
64  *  @port: port to bind to (0 for an arbitrary port)
65  *
66  *  Creates a #GUdpSocket bound to interface @iface and port @port.
67  *  If @iface is NULL, all interfaces will be used.  If @port is 0, an
68  *  arbitrary port will be used.
69  *
70  *  Returns: a new #GUdpSocket; NULL on error.
71  *
72  **/
73 GUdpSocket*
gnet_udp_socket_new_full(const GInetAddr * iface,gint port)74 gnet_udp_socket_new_full (const GInetAddr* iface, gint port)
75 {
76   SOCKET 			  sockfd;
77   struct sockaddr_storage sa;
78   GUdpSocket* 		  s;
79   const int 		  on = 1;
80 
81   /* Create sockfd and address */
82   sockfd = _gnet_create_listen_socket (SOCK_DGRAM, iface, port, &sa);
83   if (!GNET_IS_SOCKET_VALID(sockfd))
84     {
85       g_warning ("socket() failed");
86       return NULL;
87     }
88 
89   /* Set broadcast option.  This allows the user to broadcast packets.
90      It has no effect otherwise. */
91   if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
92 		 (void*) &on, sizeof(on)) != 0)
93     {
94       g_warning ("setsockopt() failed");
95       GNET_CLOSE_SOCKET(sockfd);
96       return NULL;
97     }
98 
99   /* Bind to the socket to some local address and port */
100   if (bind(sockfd, &GNET_SOCKADDR_SA(sa), GNET_SOCKADDR_LEN(sa)) != 0)
101     {
102       GNET_CLOSE_SOCKET(sockfd);
103       return NULL;
104     }
105 
106   /* Create UDP socket */
107   s = g_new0 (GUdpSocket, 1);
108   s->type = GNET_UDP_SOCKET_TYPE_COOKIE;
109   s->sockfd = sockfd;
110   s->sa = sa;
111   s->ref_count = 1;
112 
113   return s;
114 }
115 
116 
117 
118 /**
119  *  gnet_udp_socket_delete:
120  *  @socket: a #GUdpSocket, or NULL
121  *
122  *  Deletes a #GUdpSocket. Does nothing if @socket is NULL.
123  *
124  **/
125 void
gnet_udp_socket_delete(GUdpSocket * socket)126 gnet_udp_socket_delete (GUdpSocket* socket)
127 {
128   if (socket != NULL) {
129     g_return_if_fail (GNET_IS_UDP_SOCKET (socket));
130 
131     gnet_udp_socket_unref (socket);
132   }
133 }
134 
135 
136 
137 /**
138  *  gnet_udp_socket_ref
139  *  @socket: #GUdpSocket to reference
140  *
141  *  Adds a reference to a #GUdpSocket.
142  *
143  **/
144 void
gnet_udp_socket_ref(GUdpSocket * socket)145 gnet_udp_socket_ref (GUdpSocket* socket)
146 {
147   g_return_if_fail (socket != NULL);
148   g_return_if_fail (GNET_IS_UDP_SOCKET (socket));
149 
150   g_atomic_int_inc (&socket->ref_count);
151 }
152 
153 
154 /**
155  *  gnet_udp_socket_unref
156  *  @socket: a #GUdpSocket
157  *
158  *  Removes a reference from a #GUdpScoket.  A #GUdpSocket is deleted
159  *  when the reference count reaches 0.
160  *
161  **/
162 void
gnet_udp_socket_unref(GUdpSocket * socket)163 gnet_udp_socket_unref (GUdpSocket* socket)
164 {
165   g_return_if_fail (socket != NULL);
166   g_return_if_fail (GNET_IS_UDP_SOCKET (socket));
167 
168   if (g_atomic_int_dec_and_test (&socket->ref_count)) {
169     GNET_CLOSE_SOCKET (socket->sockfd);  /* Don't care if this fails... */
170 
171     if (socket->iochannel)
172       g_io_channel_unref (socket->iochannel);
173 
174     socket->type = 0;
175     g_free (socket);
176   }
177 }
178 
179 
180 
181 /**
182  *  gnet_udp_socket_get_io_channel
183  *  @socket: a #GUdpSocket
184  *
185  *  Gets the #GIOChannel of a #GUdpSocket.
186  *
187  *  Use the channel with g_io_add_watch() to check if the socket is
188  *  readable or writable.  If the channel is readable, call
189  *  gnet_udp_socket_receive() to receive a packet.  If the channel is
190  *  writable, call gnet_udp_socket_send() to send a packet.  This is
191  *  not a normal giochannel - do not read from or write to it.
192  *
193  *  Every #GUdpSocket has one and only one #GIOChannel.  If you ref
194  *  the channel, then you must unref it eventually.  Do not close the
195  *  channel.  The channel is closed by GNet when the socket is
196  *  deleted.
197  *
198  *  Before deleting the UDP socket, make sure to remove any watches you have
199  *  added with g_io_add_watch() again with g_source_remove() using the integer
200  *  id returned by g_io_add_watch(). You may find your program stuck in a busy
201  *  loop at 100% CPU utilisation if you forget to do this.
202  *
203  *  Returns: a #GIOChannel.
204  *
205  **/
206 GIOChannel*
gnet_udp_socket_get_io_channel(GUdpSocket * socket)207 gnet_udp_socket_get_io_channel (GUdpSocket* socket)
208 {
209   g_return_val_if_fail (socket != NULL, NULL);
210   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), NULL);
211 
212   if (socket->iochannel == NULL)
213     socket->iochannel = _gnet_io_channel_new (socket->sockfd);
214 
215   return socket->iochannel;
216 }
217 
218 
219 
220 /**
221  *  gnet_udp_socket_get_local_inetaddr
222  *  @socket: a #GUdpSocket
223  *
224  *  Gets the local host's address from a #GUdpSocket.
225  *
226  *  Returns: a #GInetAddr.
227  *
228  **/
229 GInetAddr*
gnet_udp_socket_get_local_inetaddr(const GUdpSocket * socket)230 gnet_udp_socket_get_local_inetaddr (const GUdpSocket* socket)
231 {
232   socklen_t socklen;
233   struct sockaddr_storage sa;
234   GInetAddr* ia;
235 
236   g_return_val_if_fail (socket, NULL);
237   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), NULL);
238 
239   socklen = sizeof(sa);
240   if (getsockname(socket->sockfd, &GNET_SOCKADDR_SA(sa), &socklen) != 0)
241     return NULL;
242 
243   ia = g_new0(GInetAddr, 1);
244   ia->ref_count = 1;
245   ia->sa = sa;
246 
247   return ia;
248 }
249 
250 
251 /**
252  *  gnet_udp_socket_send
253  *  @socket: a #GUdpSocket
254  *  @buffer: buffer to send
255  *  @length: length of @buffer
256  *  @dst: destination address
257  *
258  *  Sends data to a host using a #GUdpSocket.
259  *
260  *  Returns: 0 if successful; something else on error.
261  *
262  **/
263 gint
gnet_udp_socket_send(GUdpSocket * socket,const gchar * buffer,gint length,const GInetAddr * dst)264 gnet_udp_socket_send (GUdpSocket* socket,
265 		      const gchar* buffer, gint length,
266 		      const GInetAddr* dst)
267 {
268   gint bytes_sent;
269   struct sockaddr_storage sa;
270 
271   g_return_val_if_fail (socket != NULL, -1);
272   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), -1);
273   g_return_val_if_fail (dst != NULL, -1);
274   g_return_val_if_fail (buffer != NULL, -1);
275 
276   /* Address of dst must be address of socket */
277 #ifdef HAVE_IPV6
278   if (GNET_INETADDR_FAMILY(dst) != GNET_SOCKADDR_FAMILY(socket->sa))
279     {
280       /* If dst is IPv4, map to IPv6 */
281       if (GNET_INETADDR_FAMILY(dst) == AF_INET &&
282 	  GNET_SOCKADDR_FAMILY(socket->sa) == AF_INET6)
283 	{
284           GNET_SOCKADDR_FAMILY(sa) = AF_INET6;
285 	  GNET_SOCKADDR_SET_SS_LEN(sa);
286           GNET_SOCKADDR_PORT_SET(sa, GNET_INETADDR_PORT(dst));
287           GNET_SOCKADDR_ADDR32_SET(sa, 0, 0);
288           GNET_SOCKADDR_ADDR32_SET(sa, 1, 0);
289           GNET_SOCKADDR_ADDR32_SET(sa, 2, g_htonl(0xffff));
290           GNET_SOCKADDR_ADDR32_SET(sa, 3, GNET_INETADDR_ADDR32(dst, 0));
291 	}
292 
293       /* If dst is IPv6, map to IPv4 if possible */
294       else if (GNET_INETADDR_FAMILY(dst) == AF_INET6 &&
295                GNET_SOCKADDR_FAMILY(socket->sa) == AF_INET &&
296                IN6_IS_ADDR_V4MAPPED(&GNET_INETADDR_SA6(dst).sin6_addr))
297 	{
298           GNET_SOCKADDR_FAMILY(sa) = AF_INET;
299 	  GNET_SOCKADDR_SET_SS_LEN(sa);
300           GNET_SOCKADDR_PORT_SET(sa, GNET_INETADDR_PORT(dst));
301           GNET_SOCKADDR_ADDR32_SET(sa, 0, GNET_INETADDR_ADDR32(dst, 3));
302 	}
303       else
304         return -1;
305 
306     }
307     /* Addresses match - just copy the address */
308     else
309 #endif
310       {
311 	sa = dst->sa;
312       }
313 
314 
315   bytes_sent = sendto (socket->sockfd,
316                        (void*) buffer, length, 0,
317                        (struct sockaddr*) &sa, GNET_SOCKADDR_LEN(sa));
318 
319   if (bytes_sent != length)
320     return -1;
321 
322   return 0;
323 }
324 
325 
326 
327 /**
328  *  gnet_udp_socket_receive
329  *  @socket: a #GUdpSocket
330  *  @buffer: buffer to write to
331  *  @length: length of @buffer
332  *  @src: pointer to source address (optional)
333  *
334  *  Receives data using a #GUdpSocket.  If @src is set, the source
335  *  address is stored in the location @src points to.  The address is
336  *  caller owned.
337  *
338  *  Returns: the number of bytes received, -1 on error.
339  *
340  **/
341 gint
gnet_udp_socket_receive(GUdpSocket * socket,gchar * buffer,gint length,GInetAddr ** src)342 gnet_udp_socket_receive (GUdpSocket* socket,
343 			 gchar* buffer, gint length,
344 			 GInetAddr** src)
345 {
346   gint bytes_received;
347   struct sockaddr_storage sa;
348   socklen_t sa_len = sizeof (struct sockaddr_storage);
349 
350   g_return_val_if_fail (socket != NULL, -1);
351   g_return_val_if_fail (buffer != NULL, -1);
352   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), -1);
353 
354   bytes_received = recvfrom (socket->sockfd,
355 			     (void*) buffer, length,
356 			     0, (struct sockaddr*) &sa, &sa_len);
357 
358   if (bytes_received == -1)
359     return -1;
360 
361   if (src)
362     {
363       (*src) = g_new0 (GInetAddr, 1);
364       (*src)->sa = sa;
365       (*src)->ref_count = 1;
366     }
367 
368   return bytes_received;
369 }
370 
371 
372 #ifndef GNET_WIN32  /*********** Unix code ***********/
373 
374 
375 /**
376  *  gnet_udp_socket_has_packet
377  *  @socket: a #GUdpSocket
378  *
379  *  Tests if a #GUdpSocket has a packet waiting to be received.
380  *
381  *  Returns: TRUE if there is packet waiting, FALSE otherwise.
382  *
383  **/
384 gboolean
gnet_udp_socket_has_packet(const GUdpSocket * socket)385 gnet_udp_socket_has_packet (const GUdpSocket* socket)
386 {
387   fd_set readfds;
388   struct timeval timeout = {0, 0};
389 
390   g_return_val_if_fail (socket != NULL, FALSE);
391   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), FALSE);
392 
393   FD_ZERO (&readfds);
394   FD_SET (socket->sockfd, &readfds);
395   if ((select(socket->sockfd + 1, &readfds, NULL, NULL, &timeout)) == 1)
396     {
397       return TRUE;
398     }
399 
400   return FALSE;
401 }
402 
403 
404 #else	/*********** Windows code ***********/
405 
406 
407 gboolean
gnet_udp_socket_has_packet(const GUdpSocket * socket)408 gnet_udp_socket_has_packet (const GUdpSocket* socket)
409 {
410   gint bytes_received;
411   gchar data[1];
412   guint packetlength;
413   u_long arg;
414   gint error;
415 
416   g_return_val_if_fail (socket != NULL, FALSE);
417   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), FALSE);
418 
419   arg = 1;
420   ioctlsocket(socket->sockfd, FIONBIO, &arg); /* set to non-blocking mode */
421 
422   packetlength = 1;
423   bytes_received = recvfrom(socket->sockfd, (void*) data, packetlength,
424 			    MSG_PEEK, NULL, NULL);
425 
426   error = WSAGetLastError();
427 
428   arg = 0;
429   ioctlsocket(socket->sockfd, FIONBIO, &arg); /* set blocking mode */
430 
431   if (bytes_received == SOCKET_ERROR)
432     {
433       if (WSAEMSGSIZE != error)
434 	{
435 	  return FALSE;
436 	}
437       /* else, the buffer was not big enough, which is fine since we
438 	 just want to see if a packet is there..*/
439     }
440 
441   if (bytes_received)
442     return TRUE;
443 
444   return FALSE;
445 }
446 
447 #endif		/*********** End Windows code ***********/
448 
449 
450 
451 /**
452  *  gnet_udp_socket_get_ttl
453  *  @socket: a #GUdpSocket
454  *
455  *  Gets the time-to-live (TTL) default of a #GUdpSocket.  All UDP
456  *  packets have a TTL field.  This field is decremented by a router
457  *  before it forwards the packet.  If the TTL reaches zero, the
458  *  packet is discarded.  The default value is sufficient for most
459  *  applications.
460  *
461  *  Returns: the TTL (an integer between 0 and 255), -1 if the kernel
462  *  default is being used, or an integer less than -1 on error.
463  *
464  **/
465 gint
gnet_udp_socket_get_ttl(const GUdpSocket * socket)466 gnet_udp_socket_get_ttl (const GUdpSocket* socket)
467 {
468   int ttl;
469   socklen_t ttl_size;
470   int rv = -2;
471 
472   g_return_val_if_fail (socket != NULL, FALSE);
473   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), FALSE);
474 
475   ttl_size = sizeof(ttl);
476 
477   /* Get the IPv4 TTL if it's bound to an IPv4 address */
478   if (GNET_SOCKADDR_FAMILY(socket->sa) == AF_INET)
479     {
480       rv = getsockopt(socket->sockfd, IPPROTO_IP, IP_TTL,
481 		      (void*) &ttl, &ttl_size);
482     }
483 
484   /* Or, get the IPv6 TTL if it's bound to an IPv6 address */
485 #ifdef HAVE_IPV6
486   else if (GNET_SOCKADDR_FAMILY(socket->sa) == AF_INET6)
487     {
488       rv = getsockopt(socket->sockfd, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
489 		      (void*) &ttl, &ttl_size);
490     }
491 #endif
492   else
493     g_assert_not_reached();
494 
495 
496   if (rv == -1)
497     return -2;
498 
499   return ttl;
500 }
501 
502 
503 /**
504  *  gnet_udp_socket_set_ttl
505  *  @socket: a #GUdpSocket
506  *  @ttl: value to set TTL to
507  *
508  *  Sets the time-to-live (TTL) default of a #GUdpSocket.  Set the TTL
509  *  to -1 to use the kernel default.  The default value is sufficient
510  *  for most applications.
511  *
512  *  Returns: 0 if successful.
513  *
514  **/
515 gint
gnet_udp_socket_set_ttl(GUdpSocket * socket,gint ttl)516 gnet_udp_socket_set_ttl (GUdpSocket* socket, gint ttl)
517 {
518   int rv1, rv2;
519 #ifdef HAVE_IPV6
520   GIPv6Policy policy;
521 #endif
522 
523   g_return_val_if_fail (socket != NULL, FALSE);
524   g_return_val_if_fail (GNET_IS_UDP_SOCKET (socket), FALSE);
525 
526   rv1 = -1;
527   rv2 = -1;
528 
529   /* If the bind address is anything IPv4 *or* the bind address is
530      0::0 IPv6 and IPv6 policy allows IPv4, set IP_TTL.  In the latter case,
531      if we bind to 0::0 and the host is dual-stacked, then all IPv4
532      interfaces will be bound to also. */
533   if (GNET_SOCKADDR_FAMILY(socket->sa) == AF_INET
534 #ifdef HAVE_IPV6
535       || (GNET_SOCKADDR_FAMILY(socket->sa) == AF_INET6 &&
536        IN6_IS_ADDR_UNSPECIFIED(&GNET_SOCKADDR_SA6(socket->sa).sin6_addr) &&
537        ((policy = gnet_ipv6_get_policy()) == GIPV6_POLICY_IPV4_THEN_IPV6 ||
538 	policy == GIPV6_POLICY_IPV6_THEN_IPV4))
539 #endif
540       )
541     {
542       rv1 = setsockopt(socket->sockfd, IPPROTO_IP, IP_TTL,
543 		       (void*) &ttl, sizeof(ttl));
544     }
545 
546 
547   /* If the bind address is IPv6, set IPV6_UNICAST_HOPS */
548 #ifdef HAVE_IPV6
549   if (GNET_SOCKADDR_FAMILY(socket->sa) == AF_INET6)
550     {
551       rv2 = setsockopt(socket->sockfd, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
552 		       (void*) &ttl, sizeof(ttl));
553     }
554 #endif
555 
556   if (rv1 == -1 && rv2 == -1)
557     return -1;
558 
559   return 0;
560 }
561