1 /* GNet - Networking library
2  * Copyright (C) 2000-2003  David Helder
3  * Copyright (C) 2000-2004  Andrew Lanoix
4  * Copyright (C) 2007       Tim-Philipp Müller <tim centricular net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA  02111-1307, USA.
20  */
21 
22 #include "gnet-private.h"
23 #include "socks-private.h"
24 #include "tcp.h"
25 
26 static gboolean gnet_tcp_socket_new_async_cb (GIOChannel * iochannel,
27     GIOCondition condition, gpointer data);
28 static void gnet_tcp_socket_connect_inetaddr_cb (GList * ia_list, gpointer data);
29 static void gnet_tcp_socket_connect_tcp_cb (GTcpSocket * socket, gpointer data);
30 
31 typedef struct _GTcpSocketAsyncState
32 {
33   GTcpSocket             * socket;
34   GTcpSocketNewAsyncFunc   func;
35   gpointer                 data;
36   GDestroyNotify           notify;
37   gint                     flags;
38   GIOChannel             * iochannel;
39   guint                    connect_watch;
40 #ifdef GNET_WIN32
41   gint                     errorcode;
42 #endif
43   GMainContext           * context; /* we hold a ref */
44   gint                     priority;
45 } GTcpSocketAsyncState;
46 
47 typedef struct _GTcpSocketConnectState
48 {
49   GList * ia_list;
50   GList * ia_next;
51 
52   GInetAddrNewListAsyncID  inetaddr_id;
53   GTcpSocketNewAsyncID     tcp_id;
54 
55   gboolean in_callback;
56 
57   GTcpSocketConnectAsyncFunc func;
58   gpointer                   data;
59   GDestroyNotify             notify;
60 
61   GMainContext             * context; /* we hold a ref */
62   gint                       priority;
63 } GTcpSocketConnectState;
64 
65 /**
66  *  gnet_tcp_socket_connect
67  *  @hostname: host name
68  *  @port: port
69  *
70  *  Creates a #GTcpSocket and connects to @hostname:@port.  This
71  *  function blocks (while gnet_tcp_socket_connect_async() does not).
72  *  To get the #GInetAddr of the #GTcpSocket, call
73  *  gnet_tcp_socket_get_remote_inetaddr().
74  *
75  *  Returns: a new #GTcpSocket; NULL on error.
76  **/
77 GTcpSocket*
gnet_tcp_socket_connect(const gchar * hostname,gint port)78 gnet_tcp_socket_connect (const gchar* hostname, gint port)
79 {
80   GList* ia_list;
81   GList* i;
82   GTcpSocket* socket;
83 
84   ia_list = gnet_inetaddr_new_list (hostname, port);
85   if (ia_list == NULL)
86     return NULL;
87 
88   socket = NULL;
89   for (i = ia_list; i != NULL; i = i->next)
90     {
91       GInetAddr* ia;
92 
93       ia = (GInetAddr*) i->data;
94       socket = gnet_tcp_socket_new (ia);
95       if (socket)
96 	break;
97     }
98   for (i = ia_list; i != NULL; i = i->next)
99     gnet_inetaddr_delete ((GInetAddr*) i->data);
100   g_list_free (ia_list);
101 
102   return socket;
103 }
104 
105 
106 /**
107  *  gnet_tcp_socket_connect_async_full
108  *  @hostname: host name
109  *  @port: port
110  *  @func: callback function
111  *  @data: data to pass to @func on callback
112  *  @notify: function to call to free @data, or NULL
113  *  @context: the #GMainContext to use for notifications, or NULL for the
114  *      default GLib main context.  If in doubt, pass NULL.
115  *  @priority: the priority with which to schedule notifications in the
116  *      main context, e.g. #G_PRIORITY_DEFAULT or #G_PRIORITY_HIGH.
117  *
118  *  Asynchronously creates a #GTcpSocket and connects to
119  *  @hostname:@port.  The callback is called when the connection is
120  *  made or an error occurs.  The callback will not be called during
121  *  the call to this function.
122  *
123  *  Returns: the ID of the connection; NULL on failure.  The ID can be
124  *  used with gnet_tcp_socket_connect_async_cancel() to cancel the
125  *  connection.
126  *
127  *  Since: 2.0.8
128  **/
129 GTcpSocketConnectAsyncID
gnet_tcp_socket_connect_async_full(const gchar * hostname,gint port,GTcpSocketConnectAsyncFunc func,gpointer data,GDestroyNotify notify,GMainContext * context,gint priority)130 gnet_tcp_socket_connect_async_full (const gchar * hostname, gint port,
131     GTcpSocketConnectAsyncFunc func, gpointer data, GDestroyNotify notify,
132     GMainContext * context, gint priority)
133 {
134   GTcpSocketConnectState* state;
135 
136   g_return_val_if_fail (hostname != NULL, NULL);
137   g_return_val_if_fail (func != NULL, NULL);
138 
139   if (context == NULL)
140     context = g_main_context_default ();
141 
142   state = g_new0 (GTcpSocketConnectState, 1);
143 
144   state->func = func;
145   state->data = data;
146   state->notify = notify;
147   state->context = g_main_context_ref (context);
148   state->priority = priority;
149 
150   state->inetaddr_id = gnet_inetaddr_new_list_async_full (hostname, port,
151       gnet_tcp_socket_connect_inetaddr_cb, state, (GDestroyNotify) NULL,
152       state->context, priority);
153 
154   /* On failure, gnet_inetaddr_new_list_async_full() returns NULL.  It will
155    * not call the callback before it returns. */
156   if (state->inetaddr_id == NULL) {
157     if (state->notify)
158       state->notify (state->data);
159     g_main_context_unref (state->context);
160     g_free (state);
161     return NULL;
162   }
163 
164   return state;
165 }
166 
167 /**
168  *  gnet_tcp_socket_connect_async
169  *  @hostname: host name
170  *  @port: port
171  *  @func: callback function
172  *  @data: data to pass to @func on callback
173  *
174  *  Asynchronously creates a #GTcpSocket and connects to
175  *  @hostname:@port.  The callback is called when the connection is
176  *  made or an error occurs.  The callback will not be called during
177  *  the call to this function.
178  *
179  *  Returns: the ID of the connection; NULL on failure.  The ID can be
180  *  used with gnet_tcp_socket_connect_async_cancel() to cancel the
181  *  connection.
182  *
183  **/
184 GTcpSocketConnectAsyncID
gnet_tcp_socket_connect_async(const gchar * hostname,gint port,GTcpSocketConnectAsyncFunc func,gpointer data)185 gnet_tcp_socket_connect_async (const gchar * hostname, gint port,
186     GTcpSocketConnectAsyncFunc func, gpointer data)
187 {
188   GTcpSocketConnectAsyncID async_id;
189 
190   g_return_val_if_fail (hostname != NULL, NULL);
191   g_return_val_if_fail (func != NULL, NULL);
192 
193   async_id = gnet_tcp_socket_connect_async_full (hostname, port, func, data,
194       (GDestroyNotify) NULL, NULL, G_PRIORITY_DEFAULT);
195 
196   return async_id;
197 }
198 
199 static void
gnet_tcp_socket_connect_inetaddr_cb(GList * ia_list,gpointer data)200 gnet_tcp_socket_connect_inetaddr_cb (GList* ia_list, gpointer data)
201 {
202   GTcpSocketConnectState* state = (GTcpSocketConnectState*) data;
203 
204   if (ia_list != NULL) /* Success */
205     {
206       state->inetaddr_id = NULL;
207       state->ia_list = ia_list;
208       state->ia_next = ia_list;
209 
210       while (state->ia_next != NULL)
211 	{
212 	  GTcpSocketNewAsyncID tcp_id;
213 	  GInetAddr* ia;
214 
215 	  ia = (GInetAddr*) state->ia_next->data;
216 	  state->ia_next = state->ia_next->next;
217 
218 	  tcp_id = gnet_tcp_socket_new_async_full (ia,
219               gnet_tcp_socket_connect_tcp_cb, state, (GDestroyNotify) NULL,
220               state->context, state->priority);
221 
222 	  if (tcp_id)	/* Success */
223 	    {
224 	      state->tcp_id = tcp_id;
225 	      return;
226 	    }
227 	}
228 
229       /* Failure: We could not async connect to any address.
230          In practice, new_async() rarely fails immediately.  */
231       state->in_callback = TRUE;
232       (*state->func)(NULL, GTCP_SOCKET_CONNECT_ASYNC_STATUS_INETADDR_ERROR,
233 		     state->data);
234       state->in_callback = FALSE;
235 
236       /* FIXME: don't abuse _cancel() as free function for the state */
237       gnet_tcp_socket_connect_async_cancel (state);
238     }
239   else /* Failure */
240     {
241       state->in_callback = TRUE;
242       (*state->func)(NULL, GTCP_SOCKET_CONNECT_ASYNC_STATUS_INETADDR_ERROR,
243 		     state->data);
244       state->in_callback = FALSE;
245 
246       /* FIXME: don't abuse _cancel() as free function for the state */
247       gnet_tcp_socket_connect_async_cancel (state);
248     }
249 }
250 
251 
252 static void
gnet_tcp_socket_connect_tcp_cb(GTcpSocket * socket,gpointer data)253 gnet_tcp_socket_connect_tcp_cb (GTcpSocket* socket, gpointer data)
254 {
255   GTcpSocketConnectState* state = (GTcpSocketConnectState*) data;
256 
257   g_return_if_fail (state != NULL);
258 
259   state->tcp_id = NULL;
260 
261   /* Success */
262   if (socket != NULL)
263     {
264       state->in_callback = TRUE;
265       (*state->func)(socket, GTCP_SOCKET_CONNECT_ASYNC_STATUS_OK, state->data);
266       state->in_callback = FALSE;
267 
268       /* FIXME: don't abuse _cancel() as free function for the state */
269       gnet_tcp_socket_connect_async_cancel (state);
270 
271       return;
272     }
273 
274   /* Failure: Could not connect to address */
275 
276   /* Try other addresses */
277   while (state->ia_next != NULL)
278     {
279       GInetAddr* ia;
280       gpointer tcp_id = NULL;
281 
282       ia = (GInetAddr*) state->ia_next->data;
283       state->ia_next = state->ia_next->next;
284 
285       tcp_id = gnet_tcp_socket_new_async_full (ia,
286           gnet_tcp_socket_connect_tcp_cb, state, (GDestroyNotify) NULL,
287           state->context, state->priority);
288 
289       if (tcp_id)	/* Success */
290 	{
291 	  state->tcp_id = tcp_id;
292 	  return;
293 	}
294     }
295 
296   /* Failure: No more addresses */
297   state->in_callback = TRUE;
298   (*state->func)(NULL, GTCP_SOCKET_CONNECT_ASYNC_STATUS_TCP_ERROR, state->data);
299   state->in_callback = FALSE;
300 
301   /* FIXME: don't abuse _cancel() as free function for the state */
302   gnet_tcp_socket_connect_async_cancel (state);
303 }
304 
305 
306 /**
307  *  gnet_tcp_socket_connect_async_cancel
308  *  @id: ID of the connection
309  *
310  *  Cancels an asynchronous connection that was started with
311  *  gnet_tcp_socket_connect_async().
312  *
313  */
314 void
gnet_tcp_socket_connect_async_cancel(GTcpSocketConnectAsyncID id)315 gnet_tcp_socket_connect_async_cancel (GTcpSocketConnectAsyncID id)
316 {
317   GTcpSocketConnectState* state = (GTcpSocketConnectState*) id;
318 
319   g_return_if_fail (state != NULL);
320 
321   /* Ignore if user called in the middle of a callback */
322   if (state->in_callback)
323     return;
324 
325   if (state->ia_list)
326     {
327       GList* i;
328 
329       for (i = state->ia_list; i != NULL; i = i->next)
330 	gnet_inetaddr_delete ((GInetAddr*) i->data);
331       g_list_free (state->ia_list);
332     }
333 
334   if (state->inetaddr_id)
335       gnet_inetaddr_new_list_async_cancel (state->inetaddr_id);
336 
337   if (state->tcp_id)
338       gnet_tcp_socket_new_async_cancel (state->tcp_id);
339 
340   if (state->notify)
341     state->notify (state->data);
342 
343   g_main_context_unref (state->context);
344 
345   g_free (state);
346 }
347 
348 
349 /* **************************************** */
350 
351 
352 /**
353  *  gnet_tcp_socket_new
354  *  @addr: address
355  *
356  *  Creates a #GTcpSocket and connects to @addr.  This function
357  *  blocks.  SOCKS is used if SOCKS is enabled.
358  *
359  *  Returns: a new #GTcpSocket; NULL on error.
360  *
361  **/
362 GTcpSocket*
gnet_tcp_socket_new(const GInetAddr * addr)363 gnet_tcp_socket_new (const GInetAddr* addr)
364 {
365   g_return_val_if_fail (addr != NULL, NULL);
366 
367   /* Use SOCKS if enabled */
368   if (gnet_socks_get_enabled())
369     return _gnet_socks_tcp_socket_new (addr);
370 
371   /* Otherwise, connect directly to the address */
372   return gnet_tcp_socket_new_direct (addr);
373 }
374 
375 
376 
377 /**
378  *  gnet_tcp_socket_new_direct:
379  *  @addr: address
380  *
381  *  Creates a #GTcpSocket and connects to @addr without using SOCKS.
382  *  This function blocks.  Most users should use
383  *  gnet_tcp_socket_new().
384  *
385  *  Returns: a new #GTcpSocket; NULL on error.
386  *
387  **/
388 GTcpSocket*
gnet_tcp_socket_new_direct(const GInetAddr * addr)389 gnet_tcp_socket_new_direct (const GInetAddr* addr)
390 {
391   SOCKET		sockfd;
392   GTcpSocket* 	s;
393   int			rv;
394 
395   g_return_val_if_fail (addr != NULL, NULL);
396 
397   /* Create socket */
398   sockfd = socket (GNET_INETADDR_FAMILY(addr), SOCK_STREAM, 0);
399   if (!GNET_IS_SOCKET_VALID(sockfd))
400     {
401       g_warning ("socket() failed");
402       return NULL;
403     }
404 
405   /* Create GTcpSocket */
406   s = g_new0 (GTcpSocket, 1);
407   s->sockfd = sockfd;
408   s->ref_count = 1;
409   s->sa = addr->sa;
410 
411   /* Connect */
412   rv = connect(sockfd,
413 	       &GNET_SOCKADDR_SA(s->sa), GNET_SOCKADDR_LEN(s->sa));
414   if (rv != 0)
415     {
416       GNET_CLOSE_SOCKET(s->sockfd);
417       g_free (s);
418       return NULL;
419     }
420 
421   return s;
422 }
423 
424 
425 /* **************************************** */
426 
427 /**
428  *  gnet_tcp_socket_new_async_full:
429  *  @addr: address
430  *  @func: callback function
431  *  @data: data to pass to @func on callback
432  *  @notify: function to call to free @data, or NULL
433  *  @context: the #GMainContext to use for notifications, or NULL for the
434  *      default GLib main context.  If in doubt, pass NULL.
435  *  @priority: the priority with which to schedule notifications in the
436  *      main context, e.g. #G_PRIORITY_DEFAULT or #G_PRIORITY_HIGH.
437  *
438  *  Asynchronously creates a #GTcpSocket and connects to @addr.  The
439  *  callback is called once the connection is made or an error occurs.
440  *  The callback will not be called during the call to this function.
441  *
442  *  SOCKS is used if SOCKS is enabled.  The SOCKS negotiation will
443  *  block.
444  *
445  *  Returns: the ID of the connection; NULL on failure.  The ID can be
446  *  used with gnet_tcp_socket_new_async_cancel() to cancel the
447  *  connection.
448  *
449  *  Since: 2.0.8
450  **/
451 GTcpSocketNewAsyncID
gnet_tcp_socket_new_async_full(const GInetAddr * addr,GTcpSocketNewAsyncFunc func,gpointer data,GDestroyNotify notify,GMainContext * context,gint priority)452 gnet_tcp_socket_new_async_full (const GInetAddr * addr,
453     GTcpSocketNewAsyncFunc func, gpointer data, GDestroyNotify notify,
454     GMainContext * context, gint priority)
455 {
456   GTcpSocketNewAsyncID async_id;
457 
458   g_return_val_if_fail (addr != NULL, NULL);
459   g_return_val_if_fail (func != NULL, NULL);
460 
461   /* Use SOCKS if enabled, otherwise, connect directly to the address */
462   if (gnet_socks_get_enabled()) {
463     async_id = _gnet_socks_tcp_socket_new_async_full (addr, func, data,
464         notify, context, priority);
465   } else {
466     async_id = gnet_tcp_socket_new_async_direct_full (addr, func, data,
467         notify, context, priority);
468   }
469 
470   return async_id;
471 }
472 
473 /**
474  *  gnet_tcp_socket_new_async:
475  *  @addr: address
476  *  @func: callback function
477  *  @data: data to pass to @func on callback
478  *
479  *  Asynchronously creates a #GTcpSocket and connects to @addr.  The
480  *  callback is called once the connection is made or an error occurs.
481  *  The callback will not be called during the call to this function.
482  *
483  *  SOCKS is used if SOCKS is enabled.  The SOCKS negotiation will
484  *  block.
485  *
486  *  Returns: the ID of the connection; NULL on failure.  The ID can be
487  *  used with gnet_tcp_socket_new_async_cancel() to cancel the
488  *  connection.
489  *
490  **/
491 GTcpSocketNewAsyncID
gnet_tcp_socket_new_async(const GInetAddr * addr,GTcpSocketNewAsyncFunc func,gpointer data)492 gnet_tcp_socket_new_async (const GInetAddr * addr, GTcpSocketNewAsyncFunc func,
493     gpointer data)
494 {
495   g_return_val_if_fail (addr != NULL, NULL);
496   g_return_val_if_fail (func != NULL, NULL);
497 
498   return gnet_tcp_socket_new_async_full (addr, func, data,
499       (GDestroyNotify) NULL, NULL, G_PRIORITY_DEFAULT);
500 }
501 
502 
503 /**
504  *  gnet_tcp_socket_new_async_direct_full:
505  *  @addr: address
506  *  @func: callback function
507  *  @data: data to pass to @func on callback
508  *  @notify: function to call to free @data, or NULL
509  *  @context: the #GMainContext to use for notifications, or NULL for the
510  *      default GLib main context.  If in doubt, pass NULL.
511  *  @priority: the priority with which to schedule notifications in the
512  *      main context, e.g. #G_PRIORITY_DEFAULT or #G_PRIORITY_HIGH.
513  *
514  *  Asynchronously creates a #GTcpSocket and connects to @addr without
515  *  using SOCKS.  Most users should use gnet_tcp_socket_new_async()
516  *  instead.  The callback is called once the connection is made or an
517  *  error occurs.  The callback will not be called during the call to
518  *  this function.
519  *
520  *  Returns: the ID of the connection; NULL on failure.  The ID can be
521  *  used with gnet_tcp_socket_new_async_cancel() to cancel the
522  *  connection.
523  *
524  *  Since: 2.0.8
525  **/
526 GTcpSocketNewAsyncID
gnet_tcp_socket_new_async_direct_full(const GInetAddr * addr,GTcpSocketNewAsyncFunc func,gpointer data,GDestroyNotify notify,GMainContext * context,gint priority)527 gnet_tcp_socket_new_async_direct_full (const GInetAddr * addr,
528     GTcpSocketNewAsyncFunc func, gpointer data, GDestroyNotify notify,
529     GMainContext * context, gint priority)
530 {
531   SOCKET		sockfd;
532 #ifndef GNET_WIN32
533   gint 			flags;
534 #else
535   u_long		arg;
536 #endif
537   GTcpSocket* 		s;
538   GTcpSocketAsyncState* state;
539   gint			status;
540 
541   g_return_val_if_fail (addr != NULL, NULL);
542   g_return_val_if_fail (func != NULL, NULL);
543 
544   if (context == NULL)
545     context = g_main_context_default ();
546 
547   /* Create socket */
548   sockfd = socket(GNET_INETADDR_FAMILY(addr), SOCK_STREAM, 0);
549   if (!GNET_IS_SOCKET_VALID(sockfd))
550     {
551       g_warning ("socket() failed");
552       return NULL;
553     }
554 
555   /* Force the socket into non-blocking mode */
556 #ifndef GNET_WIN32
557   /* Get the flags (should all be 0?) */
558   flags = fcntl(sockfd, F_GETFL, 0);
559   if (flags == -1)
560     {
561       g_warning ("fcntl() failed");
562       GNET_CLOSE_SOCKET(sockfd);
563       return NULL;
564     }
565 
566   if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1)
567     {
568       g_warning ("fcntl() failed");
569       GNET_CLOSE_SOCKET(sockfd);
570       return NULL;
571     }
572 #else
573   arg = 1;
574   ioctlsocket(sockfd, FIONBIO, &arg);
575 #endif
576 
577   /* Create our structure */
578   s = g_new0(GTcpSocket, 1);
579   s->ref_count = 1;
580   s->sockfd = sockfd;
581 
582   /* Connect (but non-blocking!) */
583   status = connect(s->sockfd, &GNET_INETADDR_SA(addr),
584 		   GNET_INETADDR_LEN(addr));
585   if (STATUS_IS_SOCKET_ERROR (status))
586     {
587       if (!ERROR_IS_CONNECT_IN_PROGRESS ())
588 	{
589 	  GNET_CLOSE_SOCKET(sockfd);
590 	  g_free(s);
591 	  return NULL;
592 	}
593     }
594 
595   /* Save address */
596   s->sa = addr->sa;
597 
598   /* Note that if connect returns 0, then we're already connected and
599      we could call the call back immediately.  But, it would probably
600      make things too complicated for the user if we could call the
601      callback before we returned from this function.  */
602 
603   /* Wait for the connection */
604   state = g_new0 (GTcpSocketAsyncState, 1);
605   state->socket = s;
606   state->func = func;
607   state->data = data;
608   state->notify = notify;
609 #ifndef GNET_WIN32
610   state->flags = flags;
611 #endif
612   state->iochannel = g_io_channel_ref (gnet_tcp_socket_get_io_channel (s));
613   state->context = g_main_context_ref (context);
614   state->priority = priority;
615 
616   state->connect_watch = _gnet_io_watch_add_full (state->context,
617       state->priority, state->iochannel, GNET_ANY_IO_CONDITION,
618       gnet_tcp_socket_new_async_cb, state, NULL);
619 
620   return state;
621 }
622 
623 /**
624  *  gnet_tcp_socket_new_async_direct
625  *  @addr: address
626  *  @func: callback function
627  *  @data: data to pass to @func on callback
628  *
629  *  Asynchronously creates a #GTcpSocket and connects to @addr without
630  *  using SOCKS.  Most users should use gnet_tcp_socket_new_async()
631  *  instead.  The callback is called once the connection is made or an
632  *  error occurs.  The callback will not be called during the call to
633  *  this function.
634  *
635  *  Returns: the ID of the connection; NULL on failure.  The ID can be
636  *  used with gnet_tcp_socket_new_async_cancel() to cancel the
637  *  connection.
638  *
639  **/
640 GTcpSocketNewAsyncID
gnet_tcp_socket_new_async_direct(const GInetAddr * addr,GTcpSocketNewAsyncFunc func,gpointer data)641 gnet_tcp_socket_new_async_direct (const GInetAddr * addr,
642     GTcpSocketNewAsyncFunc func, gpointer data)
643 {
644   GTcpSocketNewAsyncID async_id;
645 
646   g_return_val_if_fail (addr != NULL, NULL);
647   g_return_val_if_fail (func != NULL, NULL);
648 
649   async_id = gnet_tcp_socket_new_async_direct_full (addr, func, data,
650       (GDestroyNotify) NULL, NULL, G_PRIORITY_DEFAULT);
651 
652   return async_id;
653 }
654 
655 
656 static gboolean
gnet_tcp_socket_new_async_cb(GIOChannel * iochannel,GIOCondition condition,gpointer data)657 gnet_tcp_socket_new_async_cb (GIOChannel* iochannel,
658 			      GIOCondition condition,
659 			      gpointer data)
660 {
661   GTcpSocketAsyncState* state = (GTcpSocketAsyncState*) data;
662   socklen_t len;
663   gint error;
664 
665   if (!((condition & G_IO_IN) || (condition & G_IO_OUT)))
666     goto error;
667 
668   len = sizeof(error);
669 
670   /* Get the error option */
671   if (getsockopt(state->socket->sockfd, SOL_SOCKET, SO_ERROR, (void*) &error, &len) < 0)
672     {
673       g_warning ("getsockopt() failed");
674       goto error;
675     }
676 
677   /* Check if there is an error */
678   if (error)
679     goto error;
680 
681 #ifndef GNET_WIN32
682   /* Reset the flags */
683   if (fcntl(state->socket->sockfd, F_SETFL, state->flags) != 0)
684     {
685       g_warning ("fcntl() failed");
686       goto error;
687     }
688 #endif
689 
690   /* Success */
691   (*state->func) (state->socket, state->data);
692 
693 done:
694 
695   state->connect_watch = 0;
696   g_io_channel_unref (state->iochannel);
697   g_main_context_unref (state->context);
698   /* FIXME: is notify really useful in this context? */
699   if (state->notify)
700     state->notify (state->data);
701   memset (state, 0xaa, sizeof (*state));
702   g_free (state);
703   return FALSE; /* don't call us again */
704 
705 /* ERROR */
706 error:
707   {
708     (*state->func) (NULL, state->data);
709     gnet_tcp_socket_delete (state->socket);
710     goto done;
711   }
712 }
713 
714 
715 /**
716  *  gnet_tcp_socket_new_async_cancel
717  *  @id: ID of the connection
718  *
719  *  Cancels an asynchronous #GTcpSocket creation that was started with
720  *  gnet_tcp_socket_new_async().
721  *
722  **/
723 void
gnet_tcp_socket_new_async_cancel(GTcpSocketNewAsyncID id)724 gnet_tcp_socket_new_async_cancel (GTcpSocketNewAsyncID id)
725 {
726   GTcpSocketAsyncState* state = (GTcpSocketAsyncState*) id;
727 
728   if (state->connect_watch)
729     _gnet_source_remove (state->context, state->connect_watch);
730   if (state->iochannel)
731     g_io_channel_unref (state->iochannel);
732   gnet_tcp_socket_delete (state->socket);
733   g_main_context_unref (state->context);
734   if (state->notify)
735     state->notify (state->data);
736   g_free (state);
737 }
738 
739 
740 
741 /**
742  *  gnet_tcp_socket_delete
743  *  @socket: a #GTcpSocket
744  *
745  *  Deletes a #GTcpSocket.
746  *
747  **/
748 void
gnet_tcp_socket_delete(GTcpSocket * socket)749 gnet_tcp_socket_delete (GTcpSocket* socket)
750 {
751   if (socket != NULL)
752     gnet_tcp_socket_unref (socket);
753 }
754 
755 
756 
757 /**
758  *  gnet_tcp_socket_ref
759  *  @socket: a #GTcpSocket
760  *
761  *  Adds a reference to a #GTcpSocket.
762  *
763  **/
764 void
gnet_tcp_socket_ref(GTcpSocket * socket)765 gnet_tcp_socket_ref (GTcpSocket* socket)
766 {
767   g_return_if_fail (socket != NULL);
768 
769   g_atomic_int_inc (&socket->ref_count);
770 }
771 
772 /* returns TRUE if the socket has been deleted (useful for io watches) */
773 static gboolean
gnet_tcp_socket_unref_internal(GTcpSocket * socket)774 gnet_tcp_socket_unref_internal (GTcpSocket * socket)
775 {
776   if (!g_atomic_int_dec_and_test (&socket->ref_count))
777     return FALSE;
778 
779   if (socket->accept_watch)
780     g_source_remove (socket->accept_watch);
781 
782   GNET_CLOSE_SOCKET (socket->sockfd); /* Don't care if this fails... */
783 
784   if (socket->iochannel)
785     g_io_channel_unref (socket->iochannel);
786 
787   g_free (socket);
788   return TRUE;
789 }
790 
791 /**
792  *  gnet_tcp_socket_unref
793  *  @socket: a #GTcpSocket to unreference
794  *
795  *  Removes a reference from a #GTcpSocket.  A #GTcpSocket is deleted
796  *  when the reference count reaches 0.
797  *
798  **/
799 void
gnet_tcp_socket_unref(GTcpSocket * socket)800 gnet_tcp_socket_unref (GTcpSocket* socket)
801 {
802   g_return_if_fail (socket != NULL);
803 
804   gnet_tcp_socket_unref_internal (socket);
805 }
806 
807 
808 
809 /**
810  *  gnet_tcp_socket_get_io_channel
811  *  @socket: a #GTcpSocket
812  *
813  *  Gets the #GIOChannel of a #GTcpSocket.
814  *
815  *  For a client socket, the #GIOChannel represents the data stream.
816  *  Use it like you would any other #GIOChannel.
817  *
818  *  For a server socket however, the #GIOChannel represents the
819  *  listening socket.  When it's readable, there's a connection
820  *  waiting to be accepted.  However, using
821  *  gnet_tcp_socket_server_accept_async() is more elegant than
822  *  watching the #GIOChannel.
823  *
824  *  Every #GTcpSocket has one and only one #GIOChannel.  If you ref
825  *  the channel, then you must unref it eventually.  Do not close the
826  *  channel.  The channel is closed by GNet when the socket is
827  *  deleted.
828  *
829  *  Returns: a #GIOChannel.
830  *
831  **/
832 GIOChannel*
gnet_tcp_socket_get_io_channel(GTcpSocket * socket)833 gnet_tcp_socket_get_io_channel (GTcpSocket* socket)
834 {
835   g_return_val_if_fail (socket != NULL, NULL);
836 
837   if (socket->iochannel == NULL)
838     socket->iochannel = _gnet_io_channel_new(socket->sockfd);
839 
840   return socket->iochannel;
841 }
842 
843 
844 /**
845  *  gnet_tcp_socket_get_remote_inetaddr
846  *  @socket: a #GTcpSocket
847  *
848  *  Gets the address of the remote host from a #GTcpSocket.  This
849  *  function does not work on server sockets.
850  *
851  *  Returns: a #GInetAddr.
852  *
853  **/
854 GInetAddr*
gnet_tcp_socket_get_remote_inetaddr(const GTcpSocket * socket)855 gnet_tcp_socket_get_remote_inetaddr (const GTcpSocket* socket)
856 {
857   GInetAddr* ia;
858 
859   g_return_val_if_fail (socket != NULL, NULL);
860 
861   ia = g_new0(GInetAddr, 1);
862   ia->sa = socket->sa;
863   ia->ref_count = 1;
864 
865   return ia;
866 }
867 
868 
869 /**
870  *  gnet_tcp_socket_get_local_inetaddr
871  *  @socket: a #GTcpSocket
872  *
873  *  Gets the local host's address from a #GTcpSocket.
874  *
875  *  Returns: a #GInetAddr, or NULL on error.  Unref with gnet_inetaddr_unref()
876  *  when no longer needed.
877  *
878  **/
879 GInetAddr*
gnet_tcp_socket_get_local_inetaddr(const GTcpSocket * socket)880 gnet_tcp_socket_get_local_inetaddr (const GTcpSocket* socket)
881 {
882   socklen_t socklen;
883   struct sockaddr_storage sa;
884   GInetAddr* ia;
885 
886   g_return_val_if_fail (socket, NULL);
887 
888   socklen = sizeof(sa);
889   if (getsockname(socket->sockfd, &GNET_SOCKADDR_SA(sa), &socklen) != 0)
890     return NULL;
891 
892   ia = g_new0(GInetAddr, 1);
893   ia->ref_count = 1;
894   ia->sa = sa;
895 
896   return ia;
897 }
898 
899 
900 /**
901  *  gnet_tcp_socket_get_port
902  *  @socket: a #GTcpSocket
903  *
904  *  Gets the port a server #GTcpSocket is bound to.
905  *
906  *  Returns: the port number.
907  *
908  **/
909 gint
gnet_tcp_socket_get_port(const GTcpSocket * socket)910 gnet_tcp_socket_get_port (const GTcpSocket* socket)
911 {
912   g_return_val_if_fail (socket != NULL, 0);
913 
914   return g_ntohs(GNET_SOCKADDR_PORT(socket->sa));
915 }
916 
917 
918 
919 /* **************************************** */
920 
921 /**
922  *  gnet_tcp_socket_set_tos
923  *  @socket: a #GTcpSocket
924  *  @tos: type of service
925  *
926  *  Sets the type-of-service (TOS) of the socket.  TOS theoretically
927  *  controls the connection's quality of service, but most routers
928  *  ignore it.  Some systems don't even support this function.  The
929  *  function does nothing if the operating system does not support it.
930  *
931  **/
932 void
gnet_tcp_socket_set_tos(GTcpSocket * socket,GNetTOS tos)933 gnet_tcp_socket_set_tos (GTcpSocket* socket, GNetTOS tos)
934 {
935   int sotos;
936 
937   g_return_if_fail (socket != NULL);
938 
939   /* Some systems (e.g. OpenBSD) do not have IPTOS_*.  Other systems
940      have some of them, but not others.  And some systems have them,
941      but with different names (e.g. FreeBSD has IPTOS_MINCOST).  If a
942      system does not have a IPTOS, or any of them, then this function
943      does nothing.  */
944   switch (tos)
945     {
946 #ifdef IPTOS_LOWDELAY
947     case GNET_TOS_LOWDELAY:	sotos = IPTOS_LOWDELAY;		break;
948 #endif
949 #ifdef IPTOS_THROUGHPUT
950     case GNET_TOS_THROUGHPUT:	sotos = IPTOS_THROUGHPUT;	break;
951 #endif
952 #ifdef IPTOS_RELIABILITY
953     case GNET_TOS_RELIABILITY:	sotos = IPTOS_RELIABILITY;	break;
954 #endif
955 #ifdef IPTOS_LOWCOST
956     case GNET_TOS_LOWCOST:	sotos = IPTOS_LOWCOST;		break;
957 #else
958 #ifdef IPTOS_MINCOST	/* Called MINCOST in FreeBSD 4.0 */
959     case GNET_TOS_LOWCOST:	sotos = IPTOS_MINCOST;		break;
960 #endif
961 #endif
962     default: return;
963     }
964 
965 #ifdef IP_TOS
966   if (setsockopt(socket->sockfd, IPPROTO_IP, IP_TOS, (void*) &sotos, sizeof(sotos)) != 0)
967     g_warning ("Can't set TOS on TCP socket\n");
968 #endif
969 
970 }
971 
972 
973 /* **************************************** */
974 /* Server stuff */
975 
976 
977 /**
978  *  gnet_tcp_socket_server_new
979  *
980  *  Creates a new #GTcpSocket bound to all interfaces and an arbitrary
981  *  port.  SOCKS is used if SOCKS is enabled.
982  *
983  *  Returns: a new #GTcpSocket; NULL on error.
984  *
985  **/
986 GTcpSocket*
gnet_tcp_socket_server_new(void)987 gnet_tcp_socket_server_new (void)
988 {
989   return gnet_tcp_socket_server_new_full (NULL, 0);
990 }
991 
992 
993 /**
994  *  gnet_tcp_socket_server_new_with_port
995  *  @port: port to bind to (0 for an arbitrary port)
996  *
997  *  Creates a new #GTcpSocket bound to all interfaces and port @port.
998  *  If @port is 0, an arbitrary port will be used.  SOCKS is used if
999  *  SOCKS is enabled.
1000  *
1001  *  Returns: a new #GTcpSocket; NULL on error.
1002  *
1003  **/
1004 GTcpSocket*
gnet_tcp_socket_server_new_with_port(gint port)1005 gnet_tcp_socket_server_new_with_port (gint port)
1006 {
1007   return gnet_tcp_socket_server_new_full (NULL, port);
1008 }
1009 
1010 
1011 /**
1012  *  gnet_tcp_socket_server_new_full
1013  *  @iface: Interface to bind to (NULL for all interfaces)
1014  *  @port: Port to bind to (0 for an arbitrary port)
1015  *
1016  *  Creates and new #GTcpSocket bound to interface @iface and port
1017  *  @port.  If @iface is NULL, the socket is bound to all interfaces.
1018  *  If @port is 0, the socket is bound to an arbitrary port.  SOCKS is
1019  *  used if SOCKS is enabled and the interface is NULL.
1020  *
1021  *  Returns: a new #GTcpSocket; NULL on error.
1022  *
1023  **/
1024 GTcpSocket*
gnet_tcp_socket_server_new_full(const GInetAddr * iface,gint port)1025 gnet_tcp_socket_server_new_full (const GInetAddr* iface, gint port)
1026 {
1027   SOCKET sockfd = 0;
1028   struct sockaddr_storage sa;
1029   GTcpSocket* s;
1030   socklen_t socklen;
1031   const int on = 1;
1032 #ifndef GNET_WIN32
1033   gint flags;
1034 #endif
1035 
1036 
1037   /* Use SOCKS if enabled */
1038   if (!iface && gnet_socks_get_enabled())
1039     return _gnet_socks_tcp_socket_server_new (port);
1040 
1041   /* Create sockfd and address */
1042   sockfd = _gnet_create_listen_socket (SOCK_STREAM, iface, port, &sa);
1043   if (!GNET_IS_SOCKET_VALID(sockfd))
1044     return NULL;
1045 
1046   /* Set REUSEADDR so we can reuse the port */
1047   if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
1048 	  (void*) &on, sizeof(on)) != 0)
1049 	      g_warning("Can't set reuse on tcp socket\n");
1050 
1051 #ifndef GNET_WIN32		/* Unix */
1052   {
1053     /* Get the flags (should all be 0?) */
1054     flags = fcntl(sockfd, F_GETFL, 0);
1055     if (flags == -1)
1056       {
1057 	g_warning ("fcntl() failed");
1058 	goto error;
1059       }
1060 
1061     /* Make the socket non-blocking */
1062     if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1)
1063       {
1064 	g_warning ("fcntl() failed");
1065 	goto error;
1066       }
1067   }
1068 #else /* Windows */
1069   {
1070     u_long arg;
1071 
1072 	/* Make the socket non-blocking */
1073     arg = 1;
1074     if (ioctlsocket(sockfd, FIONBIO, &arg))
1075       goto error;
1076     }
1077 #endif
1078 
1079   /* Bind */
1080   if (bind(sockfd, &GNET_SOCKADDR_SA(sa), GNET_SOCKADDR_LEN(sa)) != 0)
1081     goto error;
1082 
1083   /* Get the socket name */
1084   socklen = GNET_SOCKADDR_LEN(sa);
1085   if (getsockname(sockfd, &GNET_SOCKADDR_SA(sa), &socklen) != 0)
1086     goto error;
1087 
1088   /* Listen */
1089   if (listen(sockfd, 10) != 0)
1090     goto error;
1091 
1092   /* Create TcpSocket */
1093   s = g_new0(GTcpSocket, 1);
1094   s->sockfd = sockfd;
1095   s->sa = sa;
1096   s->ref_count = 1;
1097 
1098   return s;
1099 
1100  error:
1101   if (sockfd)
1102     GNET_CLOSE_SOCKET(sockfd);
1103 
1104   return NULL;
1105 }
1106 
1107 
1108 
1109 
1110 #ifndef GNET_WIN32  /*********** Unix code ***********/
1111 
1112 
1113 /**
1114  *  gnet_tcp_socket_server_accept
1115  *  @socket: a #GTcpSocket
1116  *
1117  *  Accepts a connection from a #GTcpSocket.  The socket must have
1118  *  been created using gnet_tcp_socket_server_new() (or equivalent).
1119  *  Even if the socket's #GIOChannel is readable, the function may
1120  *  still block.
1121  *
1122  *  Returns: a new #GTcpSocket representing a new connection; NULL on
1123  *  error.
1124  *
1125  **/
1126 GTcpSocket*
gnet_tcp_socket_server_accept(GTcpSocket * socket)1127 gnet_tcp_socket_server_accept (GTcpSocket* socket)
1128 {
1129   gint sockfd;
1130   struct sockaddr_storage sa;
1131   socklen_t n;
1132   fd_set fdset;
1133   GTcpSocket* s;
1134 
1135   g_return_val_if_fail (socket != NULL, NULL);
1136 
1137   if (gnet_socks_get_enabled())
1138     return _gnet_socks_tcp_socket_server_accept(socket);
1139 
1140  try_again:
1141 
1142   FD_ZERO(&fdset);
1143   FD_SET(socket->sockfd, &fdset);
1144 
1145   if (select(socket->sockfd + 1, &fdset, NULL, NULL, NULL) == -1)
1146     {
1147       if (errno == EINTR)
1148 	goto try_again;
1149 
1150       return NULL;
1151     }
1152 
1153   n = sizeof(s->sa);
1154 
1155   if ((sockfd = accept(socket->sockfd, (struct sockaddr*) &sa, &n)) == -1)
1156     {
1157       if (errno == EWOULDBLOCK ||
1158 	  errno == ECONNABORTED ||
1159 #ifdef EPROTO		/* OpenBSD does not have EPROTO */
1160 	  errno == EPROTO ||
1161 #endif
1162 	  errno == EINTR)
1163 	goto try_again;
1164 
1165       return NULL;
1166     }
1167 
1168   s = g_new0(GTcpSocket, 1);
1169   s->ref_count = 1;
1170   s->sockfd = sockfd;
1171   s->sa = sa;
1172 
1173   return s;
1174 }
1175 
1176 
1177 
1178 
1179 
1180 /**
1181  *  gnet_tcp_socket_server_accept_nonblock
1182  *  @socket: a #GTcpSocket
1183  *
1184  *  Accepts a connection from a #GTcpSocket without blocking.  The
1185  *  socket must have been created using gnet_tcp_socket_server_new()
1186  *  (or equivalent).
1187  *
1188  *  Note that if the socket's #GIOChannel is readable, then there is
1189  *  PROBABLY a new connection.  It is possible for the connection
1190  *  to close by the time this function is called, so it may return
1191  *  NULL.
1192  *
1193  *  Returns: a new #GTcpSocket representing a new connection; NULL
1194  *  otherwise.
1195  *
1196  **/
1197 GTcpSocket*
gnet_tcp_socket_server_accept_nonblock(GTcpSocket * socket)1198 gnet_tcp_socket_server_accept_nonblock (GTcpSocket* socket)
1199 {
1200   gint sockfd;
1201   struct sockaddr_storage sa;
1202   socklen_t n;
1203   fd_set fdset;
1204   GTcpSocket* s;
1205   struct timeval tv = {0, 0};
1206 
1207   g_return_val_if_fail (socket != NULL, NULL);
1208 
1209   if (gnet_socks_get_enabled())
1210     return _gnet_socks_tcp_socket_server_accept(socket);
1211 
1212  try_again:
1213 
1214   FD_ZERO(&fdset);
1215   FD_SET(socket->sockfd, &fdset);
1216 
1217   if (select(socket->sockfd + 1, &fdset, NULL, NULL, &tv) == -1)
1218     {
1219       if (errno == EINTR)
1220 	goto try_again;
1221 
1222       return NULL;
1223     }
1224 
1225   n = sizeof(sa);
1226   if ((sockfd = accept(socket->sockfd, (struct sockaddr*) &sa, &n)) == -1)
1227     {
1228       /* If we get an error, return.  We don't want to try again as we
1229          do in gnet_tcp_socket_server_accept() - it might cause a
1230          block. */
1231 
1232       return NULL;
1233     }
1234 
1235   s = g_new0(GTcpSocket, 1);
1236   s->ref_count = 1;
1237   s->sockfd = sockfd;
1238   s->sa = sa;
1239 
1240   return s;
1241 }
1242 
1243 
1244 #else	/*********** Windows code ***********/
1245 
1246 
1247 GTcpSocket*
gnet_tcp_socket_server_accept(GTcpSocket * socket)1248 gnet_tcp_socket_server_accept (GTcpSocket* socket)
1249 {
1250   SOCKET sockfd;
1251   struct sockaddr_storage sa;
1252   fd_set fdset;
1253   GTcpSocket* s;
1254   socklen_t n;
1255 
1256   g_return_val_if_fail (socket != NULL, NULL);
1257 
1258   if (gnet_socks_get_enabled())
1259     return _gnet_socks_tcp_socket_server_accept(socket);
1260 
1261   FD_ZERO(&fdset);
1262   FD_SET((unsigned)socket->sockfd, &fdset);
1263 
1264   if (select((int)socket->sockfd + 1, &fdset, NULL, NULL, NULL) == -1)
1265       return NULL;
1266 
1267   /* Don't force the socket into blocking mode */
1268 
1269   n = sizeof(sa);
1270   sockfd = accept(socket->sockfd, (struct sockaddr*) &sa, &n);
1271   /* if it fails, looping isn't going to help */
1272 
1273   if (!GNET_IS_SOCKET_VALID(sockfd))
1274       return NULL;
1275 
1276   s = g_new0(GTcpSocket, 1);
1277   s->ref_count = 1;
1278   s->sockfd = sockfd;
1279   s->sa = sa;
1280 
1281   return s;
1282 }
1283 
1284 
1285 GTcpSocket*
gnet_tcp_socket_server_accept_nonblock(GTcpSocket * socket)1286 gnet_tcp_socket_server_accept_nonblock (GTcpSocket* socket)
1287 {
1288   SOCKET sockfd;
1289   struct sockaddr_storage sa;
1290 
1291   fd_set fdset;
1292   GTcpSocket* s;
1293   u_long arg;
1294   socklen_t n;
1295 
1296   g_return_val_if_fail (socket != NULL, NULL);
1297 
1298   if (gnet_socks_get_enabled())
1299     return _gnet_socks_tcp_socket_server_accept(socket);
1300 
1301   FD_ZERO(&fdset);
1302   FD_SET((unsigned)socket->sockfd, &fdset);
1303 
1304   if (select((int)socket->sockfd + 1, &fdset, NULL, NULL, NULL) == -1)
1305       return NULL;
1306 
1307   /* make sure the socket is in non-blocking mode */
1308   arg = 1;
1309   if (ioctlsocket(socket->sockfd, FIONBIO, &arg))
1310     return NULL;
1311 
1312   n = sizeof(sa);
1313   sockfd = accept(socket->sockfd, (struct sockaddr*) &sa, &n);
1314   /* if it fails, looping isn't going to help */
1315 
1316   if (sockfd == INVALID_SOCKET)
1317       return NULL;
1318 
1319   s = g_new0(GTcpSocket, 1);
1320   s->ref_count = 1;
1321   s->sockfd = sockfd;
1322   s->sa = sa;
1323 
1324   return s;
1325 }
1326 
1327 
1328 #endif		/*********** End Windows code ***********/
1329 
1330 
1331 
1332 static gboolean tcp_socket_server_accept_async_cb (GIOChannel* iochannel,
1333 						   GIOCondition condition,
1334 						   gpointer data);
1335 
1336 /**
1337  *  gnet_tcp_socket_server_accept_async:
1338  *  @socket: a #GTcpSocket
1339  *  @accept_func: callback function.
1340  *  @user_data: data to pass to @func on callback
1341  *
1342  *  Asynchronously accepts a connection from a #GTcpSocket.  The
1343  *  callback is called when a new client has connected or an error
1344  *  occurs.  The socket must have been created using
1345  *  gnet_tcp_socket_server_new() (or equivalent).
1346  *
1347  **/
1348 void
gnet_tcp_socket_server_accept_async(GTcpSocket * socket,GTcpSocketAcceptFunc accept_func,gpointer user_data)1349 gnet_tcp_socket_server_accept_async (GTcpSocket* socket,
1350 				     GTcpSocketAcceptFunc accept_func,
1351 				     gpointer user_data)
1352 {
1353   GIOChannel* iochannel;
1354 
1355   g_return_if_fail (socket);
1356   g_return_if_fail (accept_func);
1357   g_return_if_fail (!socket->accept_func);
1358 
1359   if (gnet_socks_get_enabled())
1360     {
1361       _gnet_socks_tcp_socket_server_accept_async (socket, accept_func, user_data);
1362       return;
1363     }
1364 
1365   /* Save callback */
1366   socket->accept_func = accept_func;
1367   socket->accept_data = user_data;
1368 
1369   /* Add read watch */
1370   iochannel = gnet_tcp_socket_get_io_channel (socket);
1371   socket->accept_watch = g_io_add_watch(iochannel,
1372 					G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1373 					tcp_socket_server_accept_async_cb, socket);
1374 }
1375 
1376 
1377 
1378 static gboolean
tcp_socket_server_accept_async_cb(GIOChannel * iochannel,GIOCondition condition,gpointer data)1379 tcp_socket_server_accept_async_cb (GIOChannel* iochannel, GIOCondition condition,
1380 				   gpointer data)
1381 {
1382   GTcpSocket* server = (GTcpSocket*) data;
1383   g_assert (server != NULL);
1384 
1385   if (condition & G_IO_IN)
1386     {
1387       GTcpSocket* client;
1388 
1389       client = gnet_tcp_socket_server_accept_nonblock (server);
1390       if (!client)
1391 	return TRUE;
1392 
1393       /* Do upcall, protected by a ref */
1394       gnet_tcp_socket_ref (server);
1395 
1396       (server->accept_func)(server, client, server->accept_data);
1397 
1398       if (gnet_tcp_socket_unref_internal (server) || !server->accept_watch)
1399 	return FALSE;
1400     }
1401   else
1402     {
1403       gnet_tcp_socket_ref (server);
1404       (server->accept_func)(server, NULL, server->accept_data);
1405       server->accept_watch = 0;
1406       server->accept_func = NULL;
1407       server->accept_data = NULL;
1408       gnet_tcp_socket_unref (server);
1409       return FALSE;
1410     }
1411 
1412   return TRUE;
1413 }
1414 
1415 
1416 
1417 /**
1418  *  gnet_tcp_socket_server_accept_async_cancel
1419  *  @socket: a #GTcpSocket
1420  *
1421  *  Stops asynchronously accepting connections for a #GTcpSocket.  The
1422  *  socket is not closed.
1423  *
1424  **/
1425 void
gnet_tcp_socket_server_accept_async_cancel(GTcpSocket * socket)1426 gnet_tcp_socket_server_accept_async_cancel (GTcpSocket* socket)
1427 {
1428   g_return_if_fail (socket);
1429 
1430   if (!socket->accept_watch)
1431     return;
1432 
1433   socket->accept_func = NULL;
1434   socket->accept_data = NULL;
1435 
1436   g_source_remove (socket->accept_watch);
1437   socket->accept_watch = 0;
1438 }
1439