1 /* GNet - Networking library
2  * Copyright (C) 2000  David Helder
3  * Copyright (C) 2003-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 
23 #include "conn.h"
24 
25 #include <stdio.h>
26 #include <memory.h> /* required for windows */
27 #include <string.h> /* needed for g_memmove/memmove */
28 
29 #include "gnet-private.h"
30 
31 #define IS_CONNECTED(C)  ((C)->socket != NULL)
32 #define BUFFER_LEN	 1024
33 
34 /* FIXME: these macros are horrid, get rid of them */
35 #define IS_WATCHING(C, FLAG) (((C)->watch_flags & (FLAG))?TRUE:FALSE)
36 
37 #define ADD_WATCH(C, FLAG)	do {			\
38   if (!IS_WATCHING(C,FLAG)) 	{			\
39     (C)->watch_flags |= (FLAG);				\
40     if ((C)->iochannel) {				\
41       if ((C)->watch)					\
42         _gnet_source_remove ((C)->context, (C)->watch);	\
43       (C)->watch = _gnet_io_watch_add_full ((C)->context,\
44           G_PRIORITY_DEFAULT, (C)->iochannel,		\
45           (C)->watch_flags, async_cb, (C), NULL);	\
46  }}} while (0)
47 
48 #define REMOVE_WATCH(C, FLAG)	do {			\
49   if (IS_WATCHING(C,FLAG)) 	{			\
50     (C)->watch_flags &= ~(FLAG);			\
51     if ((C)->iochannel) {				\
52       if ((C)->watch)					\
53         _gnet_source_remove ((C)->context, (C)->watch);	\
54         (C)->watch = 0;					\
55       if ((C)->watch_flags != 0)			\
56         (C)->watch = _gnet_io_watch_add_full ((C)->context, \
57             G_PRIORITY_DEFAULT, (C)->iochannel,		\
58             (C)->watch_flags, async_cb, (C), NULL);	\
59  }}} while (0)
60 
61 #define UNSET_WATCH (C, FLAG)
62 
63 
64 typedef struct _Write
65 {
66   gchar* 	buffer;
67   gint 		length;
68   GDestroyNotify buffer_destroy_cb;
69 } Write;
70 
71 
72 typedef struct _Read
73 {
74   gint mode;
75 
76 } Read;
77 
78 
79 
80 static void 	ref_internal (GConn* conn);
81 static void 	unref_internal (GConn* conn);
82 
83 static void 	conn_new_cb (GTcpSocket* socket, gpointer user_data);
84 
85 static void 	conn_connect_cb (GTcpSocket* socket,
86 				 GTcpSocketConnectAsyncStatus status,
87 				 gpointer user_data);
88 
89 
90 
91 static gboolean async_cb (GIOChannel* iochannel, GIOCondition condition,
92 			  gpointer data);
93 
94 static void	conn_read_full (GConn* conn, gint mode);
95 static void	conn_check_read_queue (GConn* conn);
96 static void     conn_read_async_cb (GConn* conn);
97 static gboolean process_read_buffer_cb (gpointer data);
98 static gint	bytes_processable (GConn* conn);
99 static gint	process_read_buffer (GConn* conn);
100 
101 
102 static void 	conn_write_async_cb (GConn* conn);
103 static void 	conn_check_write_queue (GConn* conn);
104 
105 static gboolean conn_timeout_cb (gpointer data);
106 
107 
108 
109 
110 /**
111  *  gnet_conn_new
112  *  @hostname: name of host to connect to
113  *  @port: port to connect to
114  *  @func: function to call on #GConn events
115  *  @user_data: data to pass to @func on callbacks
116  *
117  *  Creates a #GConn.  A connection is not made until
118  *  gnet_conn_connect() is called.  The callback @func is called when
119  *  events occur.
120  *
121  *  Returns: a #GConn.
122  *
123  **/
124 GConn*
gnet_conn_new(const gchar * hostname,gint port,GConnFunc func,gpointer user_data)125 gnet_conn_new (const gchar* hostname, gint port,
126 	       GConnFunc func, gpointer user_data)
127 {
128   GConn* conn;
129 
130   g_return_val_if_fail (hostname, NULL);
131 
132   conn = g_new0 (GConn, 1);
133   conn->ref_count = 1;
134   conn->hostname = g_strdup(hostname);
135   conn->port = port;
136   conn->inetaddr = gnet_inetaddr_new_nonblock (hostname, port);
137   conn->func = func;
138   conn->user_data = user_data;
139 
140   return conn;
141 }
142 
143 
144 
145 /**
146  *  gnet_conn_new_inetaddr
147  *  @inetaddr: address of host to connect to
148  *  @func: function to call on #GConn events
149  *  @user_data: data to pass to @func on callbacks
150  *
151  *  Creates a #GConn.  A connection is not made until
152  *  gnet_conn_connect() is called.  The callback @func is called when
153  *  events occur.
154  *
155  *  Returns: a #GConn.
156  *
157  **/
158 GConn*
gnet_conn_new_inetaddr(const GInetAddr * inetaddr,GConnFunc func,gpointer user_data)159 gnet_conn_new_inetaddr (const GInetAddr* inetaddr,
160 			GConnFunc func, gpointer user_data)
161 {
162   GConn* conn;
163 
164   g_return_val_if_fail (inetaddr, NULL);
165 
166   conn = g_new0 (GConn, 1);
167   conn->ref_count = 1;
168   conn->hostname = gnet_inetaddr_get_canonical_name (inetaddr);
169   conn->port = gnet_inetaddr_get_port (inetaddr);
170   conn->inetaddr = gnet_inetaddr_clone (inetaddr);
171   conn->func = func;
172   conn->user_data = user_data;
173 
174   return conn;
175 }
176 
177 
178 
179 /**
180  *  gnet_conn_new_socket
181  *  @socket: TCP Socket (callee owned)
182  *  @func: function to call on #GConn events
183  *  @user_data: data to pass to @func on callbacks
184  *
185  *  Creates a #GConn.  The #GConn is created from the @socket.  The
186  *  socket is callee owned - do not delete it (meaning: #GConn will take
187  *  ownership of the socket).  The callback is called when events occur.
188  *
189  *  Returns: a #GConn.
190  *
191  **/
192 GConn*
gnet_conn_new_socket(GTcpSocket * socket,GConnFunc func,gpointer user_data)193 gnet_conn_new_socket (GTcpSocket* socket,
194 		      GConnFunc func, gpointer user_data)
195 {
196   GConn* conn;
197 
198   g_return_val_if_fail (socket, NULL);
199 
200   conn = g_new0 (GConn, 1);
201   conn->ref_count = 1;
202   conn->socket = socket;
203   conn->iochannel = gnet_tcp_socket_get_io_channel (socket);
204   conn->inetaddr = gnet_tcp_socket_get_remote_inetaddr (socket);
205   conn->hostname = gnet_inetaddr_get_canonical_name (conn->inetaddr);
206   conn->port = gnet_inetaddr_get_port (conn->inetaddr);
207   conn->func = func;
208   conn->user_data = user_data;
209 
210   return conn;
211 
212 }
213 
214 /**
215  *  gnet_conn_set_main_context
216  *  @conn: a #GConn
217  *  @context: a #GMainContext, or NULL to use the default GLib main context
218  *
219  *  Sets the GLib #GMainContext to use for asynchronous operations. You should
220  *  call this function right after you create @conn. You must not call this
221  *  function after the actual connection process has started or watches have
222  *  been set up (e.g. for reading, writing or errors).
223  *
224  *  You are very unlikely to ever need this function.
225  *
226  *  Returns: TRUE on success, FALSE on failure.
227  *
228  *  Since: 2.0.8
229  **/
230 gboolean
gnet_conn_set_main_context(GConn * conn,GMainContext * context)231 gnet_conn_set_main_context (GConn * conn, GMainContext * context)
232 {
233   g_return_val_if_fail (conn != NULL, FALSE);
234 
235   /* Must not be called if already connected or connection pending; should
236    * be okay if the socket is connected but no watches set up yet */
237   g_return_val_if_fail (conn->connect_id == 0 && conn->new_id == 0, FALSE);
238   g_return_val_if_fail (conn->watch == 0, FALSE);
239 
240   if (conn->context != context) {
241     if (conn->context)
242       g_main_context_unref (conn->context);
243     if (context)
244       conn->context = g_main_context_ref (context);
245     else
246       conn->context = NULL;
247   }
248 
249   return TRUE;
250 }
251 
252 /**
253  *  gnet_conn_delete
254  *  @conn: a #GConn
255  *
256  *  Deletes a #GConn.
257  *
258  *  Deprecated: Use g_conn_unref(), which does the same.
259  **/
260 void
gnet_conn_delete(GConn * conn)261 gnet_conn_delete (GConn* conn)
262 {
263   if (conn != NULL)
264     gnet_conn_unref(conn);
265 }
266 
267 
268 /**
269  *  gnet_conn_ref
270  *  @conn: a #GConn
271  *
272  *  Adds a reference to a #GConn.
273  *
274  **/
275 void
gnet_conn_ref(GConn * conn)276 gnet_conn_ref (GConn* conn)
277 {
278   g_return_if_fail (conn);
279 
280   conn->ref_count++;
281 }
282 
283 
284 /**
285  *  gnet_conn_unref
286  *  @conn: a #GConn
287  *
288  *  Removes a reference from a #GConn.  A #GConn is deleted when the
289  *  reference count reaches 0.
290  *
291  **/
292 void
gnet_conn_unref(GConn * conn)293 gnet_conn_unref (GConn* conn)
294 {
295   g_return_if_fail (conn);
296 
297   conn->ref_count--;
298   if (conn->ref_count > 0 || conn->ref_count_internal > 0)
299     return;
300 
301   gnet_conn_disconnect (conn);
302 
303   g_free (conn->hostname);
304 
305   if (conn->inetaddr)
306     gnet_inetaddr_delete (conn->inetaddr);
307 
308   g_free (conn->buffer);
309 
310   g_free (conn);
311 }
312 
313 
314 /* increment internal ref count.  This is used to prevent deletion
315    during a callback.  We don't want the conn to be deleted during a
316    callback if we must still access the conn after the callback.  */
317 static void
ref_internal(GConn * conn)318 ref_internal (GConn* conn)
319 {
320   g_return_if_fail (conn);
321 
322   conn->ref_count_internal++;
323 }
324 
325 
326 static void
unref_internal(GConn * conn)327 unref_internal (GConn* conn)
328 {
329   g_return_if_fail (conn);
330 
331   conn->ref_count_internal--;
332   if (conn->ref_count == 0 && conn->ref_count_internal == 0)
333     {
334       /* set ref_count to 1 to force deletion on unref. */
335       conn->ref_count = 1;
336       gnet_conn_unref (conn);
337     }
338 }
339 
340 
341 
342 /**
343  *  gnet_conn_set_callback
344  *  @conn: a #GConn
345  *  @func: function to call on #GConn events
346  *  @user_data: data to pass to @func on callbacks
347  *
348  *  Sets the #GConnEvent callback for a #GConn.  The callback @func is
349  *  called when events occur.
350  *
351  **/
352 void
gnet_conn_set_callback(GConn * conn,GConnFunc func,gpointer user_data)353 gnet_conn_set_callback (GConn* conn, GConnFunc func, gpointer user_data)
354 {
355   g_return_if_fail (conn);
356   conn->func = func;
357   conn->user_data = user_data;
358 }
359 
360 
361 
362 /**
363  *  gnet_conn_connect
364  *  @conn: a #GConn
365  *
366  *  Establishes a connection.  If the connection is pending or already
367  *  established, this function does nothing.  The callback is called
368  *  when the connection is established or an error occurs.
369  *
370  **/
371 void
gnet_conn_connect(GConn * conn)372 gnet_conn_connect (GConn * conn)
373 {
374   g_return_if_fail (conn != NULL);
375   g_return_if_fail (conn->func != NULL);
376 
377   /* Ignore if connected or connection pending */
378   if (conn->connect_id != 0 || conn->new_id != 0 || conn->socket != NULL)
379     return;
380 
381   /* Make asynchronous connection */
382   if (conn->inetaddr) {
383     conn->new_id = gnet_tcp_socket_new_async_full (conn->inetaddr,
384         conn_new_cb, conn, (GDestroyNotify) NULL, conn->context,
385         G_PRIORITY_DEFAULT);
386   } else if (conn->hostname) {
387     conn->connect_id = gnet_tcp_socket_connect_async_full (conn->hostname,
388         conn->port, conn_connect_cb, conn, (GDestroyNotify) NULL,
389         conn->context, G_PRIORITY_DEFAULT);
390   } else {
391     g_return_if_reached ();
392   }
393 }
394 
395 
396 static void
conn_new_cb(GTcpSocket * socket,gpointer user_data)397 conn_new_cb (GTcpSocket* socket, gpointer user_data)
398 {
399   GConn* conn = (GConn*) user_data;
400   GConnEvent event;
401 
402   g_return_if_fail (conn);
403 
404   conn->new_id = NULL;
405 
406   if (socket)
407     {
408       conn->socket = socket;
409       conn->iochannel = gnet_tcp_socket_get_io_channel (socket);
410 
411       conn_check_write_queue (conn);
412       conn_check_read_queue (conn);
413       if (conn->watch_flags) ADD_WATCH(conn, 0);
414 
415       event.type = GNET_CONN_CONNECT;
416     }
417   else
418     {
419       event.type = GNET_CONN_ERROR;
420     }
421 
422   event.buffer = NULL;
423   event.length = 0;
424   (conn->func)(conn, &event, conn->user_data);
425 }
426 
427 
428 static void
conn_connect_cb(GTcpSocket * socket,GTcpSocketConnectAsyncStatus status,gpointer user_data)429 conn_connect_cb (GTcpSocket* socket,
430 		 GTcpSocketConnectAsyncStatus status,
431 		 gpointer user_data)
432 {
433   GConn* conn = (GConn*) user_data;
434   GConnEvent event;
435 
436   g_return_if_fail (conn);
437 
438   conn->connect_id = NULL;
439 
440   if (status == GTCP_SOCKET_CONNECT_ASYNC_STATUS_OK)
441     {
442       conn->socket = socket;
443       conn->inetaddr = gnet_tcp_socket_get_remote_inetaddr (socket);
444       conn->iochannel = gnet_tcp_socket_get_io_channel (socket);
445 
446       conn_check_write_queue (conn);
447       conn_check_read_queue (conn);
448       if (conn->watch_flags) ADD_WATCH(conn, 0);
449 
450       event.type = GNET_CONN_CONNECT;
451     }
452   else
453     {
454       event.type = GNET_CONN_ERROR;
455     }
456 
457   event.buffer = NULL;
458   event.length = 0;
459   (conn->func)(conn, &event, conn->user_data);
460 }
461 
462 
463 static void
conn_write_free(Write * write)464 conn_write_free(Write *write)
465 {
466   if (write->buffer_destroy_cb)
467     write->buffer_destroy_cb(write->buffer);
468   g_free (write);
469 }
470 
471 
472 /**
473  *  gnet_conn_disconnect
474  *  @conn: a #GConn
475  *
476  *  Closes the connection.  The connection can later be reestablished
477  *  by calling gnet_conn_connect() again.  If the connection was not
478  *  established, this function does nothing.
479  *
480  **/
481 void
gnet_conn_disconnect(GConn * conn)482 gnet_conn_disconnect (GConn* conn)
483 {
484   GList* i;
485 
486   g_return_if_fail (conn);
487 
488   if (conn->watch)
489     {
490       _gnet_source_remove (conn->context, conn->watch);
491       conn->watch = 0;
492     }
493   conn->watch_flags = 0;
494 
495   conn->watch_readable = FALSE;
496   conn->watch_writable = FALSE;
497 
498   if (conn->iochannel)
499     conn->iochannel = NULL;	/* do not unref */
500 
501   if (conn->socket)
502     {
503       gnet_tcp_socket_delete (conn->socket);
504       conn->socket = NULL;
505     }
506 
507   if (conn->connect_id)
508     {
509       gnet_tcp_socket_connect_async_cancel (conn->connect_id);
510       conn->connect_id = NULL;
511     }
512 
513   if (conn->new_id)
514     {
515       gnet_tcp_socket_new_async_cancel (conn->new_id);
516       conn->new_id = NULL;
517     }
518 
519   for (i = conn->write_queue; i != NULL; i = i->next)
520     {
521       conn_write_free(i->data);
522     }
523   g_list_free (conn->write_queue);
524   conn->write_queue = NULL;
525   conn->bytes_written = 0;
526 
527   for (i = conn->read_queue; i != NULL; i = i->next)
528     {
529       Read* read = i->data;
530       g_free (read);
531     }
532   g_list_free (conn->read_queue);
533   conn->read_queue = NULL;
534   conn->bytes_read = 0;
535   conn->read_eof = FALSE;
536   if (conn->process_buffer_timeout)
537     {
538       _gnet_source_remove (conn->context, conn->process_buffer_timeout);
539       conn->process_buffer_timeout = 0;
540     }
541 
542   if (conn->timer)
543     {
544       _gnet_source_remove (conn->context, conn->timer);
545       conn->timer = 0;
546     }
547 }
548 
549 
550 /**
551  *  gnet_conn_is_connected
552  *  @conn: a #GConn
553  *
554  *  Checks if the connection is established.
555  *
556  *  Returns: TRUE if the connection is established, FALSE otherwise.
557  *
558  **/
559 gboolean
gnet_conn_is_connected(const GConn * conn)560 gnet_conn_is_connected (const GConn* conn)
561 {
562   g_return_val_if_fail (conn, FALSE);
563 
564   if (IS_CONNECTED(conn))
565     return TRUE;
566 
567   return FALSE;
568 }
569 
570 
571 /* **************************************** */
572 
573 static gboolean
async_cb(GIOChannel * iochannel,GIOCondition condition,gpointer data)574 async_cb (GIOChannel* iochannel, GIOCondition condition, gpointer data)
575 {
576   GConn* conn = (GConn*) data;
577   GConnEvent event = {GNET_CONN_ERROR, NULL, 0};
578 
579   ref_internal (conn);
580 
581   if (condition & (G_IO_ERR | G_IO_NVAL))
582     {
583       /* Upcall ERROR */
584       gnet_conn_disconnect (conn);
585       if (conn->func)
586 	(conn->func) (conn, &event, conn->user_data);
587 
588       unref_internal (conn);
589       return FALSE;
590     }
591 
592   if (condition & G_IO_IN)
593     {
594       /* Upcall */
595       if (conn->watch_readable)		/* READABLE */
596 	{
597 	  GConnEvent event;
598 
599 	  event.type = GNET_CONN_READABLE;
600 	  event.buffer = NULL;
601 	  event.length = 0;
602 
603 	  g_return_val_if_fail (conn->func, FALSE);
604 	  (conn->func) (conn, &event, conn->user_data);
605 	}
606       else
607 	{
608 	  conn_read_async_cb (conn);	/* READ? */
609 	}
610 
611       if (conn->ref_count == 0 || !IS_CONNECTED(conn))
612 	{
613 	  unref_internal (conn);
614 	  return FALSE;
615 	}
616     }
617 
618   if (condition & G_IO_OUT)
619     {
620       /* Upcall */
621       if (conn->watch_writable)		/* WRITABLE */
622 	{
623 	  GConnEvent event;
624 
625 	  event.type = GNET_CONN_WRITABLE;
626 	  event.buffer = NULL;
627 	  event.length = 0;
628 
629 	  g_return_val_if_fail (conn->func, FALSE);
630 	  (conn->func) (conn, &event, conn->user_data);
631 	}
632       else				/* WRITE? */
633 	{
634 	  conn_write_async_cb (conn);
635 	}
636 
637       if (conn->ref_count == 0 || !IS_CONNECTED(conn))
638 	{
639 	  unref_internal (conn);
640 	  return FALSE;
641 	}
642     }
643 
644   if (condition & G_IO_HUP)
645     {
646       gnet_conn_disconnect (conn);
647       event.type = GNET_CONN_CLOSE;
648       if (conn->func)
649 	(conn->func) (conn, &event, conn->user_data);
650     }
651 
652   unref_internal (conn);
653   /* Assume we want another callback, even though the source may have
654      been destroyed though.  The Glib main loop handles this
655      properly. */
656 
657   return TRUE;
658 }
659 
660 
661 /* **************************************** */
662 
663 
664 /**
665  *  gnet_conn_read:
666  *  @conn: a #GConn
667  *
668  *  Begins an asynchronous read.  The connection callback is called
669  *  when any data has been read.  This function may be called again
670  *  before the asynchronous read completes.
671  *
672  **/
673 void
gnet_conn_read(GConn * conn)674 gnet_conn_read (GConn* conn)
675 {
676   g_return_if_fail (conn);
677   g_return_if_fail (conn->func);
678 
679   conn_read_full (conn, 0);
680 }
681 
682 
683 /**
684  *  gnet_conn_readn:
685  *  @conn: a #GConn
686  *  @length: Number of bytes to read
687  *
688  *  Begins an asynchronous read of exactly @length bytes.  The
689  *  connection callback is called when the data has been read.  This
690  *  function may be called again before the asynchronous read
691  *  completes.
692  *
693  **/
694 void
gnet_conn_readn(GConn * conn,gint n)695 gnet_conn_readn (GConn* conn, gint n)
696 {
697   g_return_if_fail (conn);
698   g_return_if_fail (conn->func);
699   g_return_if_fail (n > 0);
700 
701   conn_read_full (conn, n);
702 
703 }
704 
705 
706 
707 /**
708  *  gnet_conn_readline:
709  *  @conn: a #GConn
710  *
711  *  Begins an asynchronous line read.  The connection callback is
712  *  called when a line has been read.  Lines are terminated with \n,
713  *  \r, \r\n, or \0.  The terminator is \0'ed out in the buffer.  The
714  *  terminating \0 is accounted for in the buffer length.  This
715  *  function may be called again before the asynchronous read
716  *  completes.
717  *
718  **/
719 void
gnet_conn_readline(GConn * conn)720 gnet_conn_readline (GConn* conn)
721 {
722   g_return_if_fail (conn);
723   g_return_if_fail (conn->func);
724 
725   conn_read_full (conn, -1);
726 }
727 
728 
729 
730 static void
conn_read_full(GConn * conn,gint mode)731 conn_read_full (GConn* conn, gint mode)
732 {
733   Read* read;
734 
735   g_return_if_fail (conn);
736 
737   /* Create the buffer */
738   if (!conn->buffer)
739     {
740       conn->buffer = g_malloc (BUFFER_LEN);
741       conn->length = BUFFER_LEN;
742       conn->bytes_read = 0;
743     }
744 
745   /* Add to read queue */
746   read = g_new0 (Read, 1);
747   read->mode = mode;
748   conn->read_queue = g_list_append (conn->read_queue, read);
749 
750   /* Check the read queue */
751   conn_check_read_queue (conn);
752 }
753 
754 
755 static void
conn_check_read_queue(GConn * conn)756 conn_check_read_queue (GConn* conn)
757 {
758   /* Ignore if we are unconnected or there are no reads */
759   if (!IS_CONNECTED(conn) || !conn->read_queue)
760     return;
761 
762   /* Ignore if we will process the buffer or are already watch IN */
763   if (conn->process_buffer_timeout || IS_WATCHING(conn, G_IO_IN))
764     return;
765 
766 
767   /* Set up process_read_buffer_cb() if there's data available and we
768      can process it, OR if we've read EOF.  EOF is
769 
770      EOF is handled when it is read, regardless of the read queue.  We
771      don't worry about it here.
772 
773      OPTIMIZATION: There may be reads in the queue that cannot be
774      processed given the data we have and we would need to read in
775      more data.  We watch IO_IN in this case.  */
776   if ((conn->bytes_read && bytes_processable(conn) > 0) || conn->read_eof) {
777     conn->process_buffer_timeout = _gnet_timeout_add_full (conn->context,
778         G_PRIORITY_DEFAULT, 0, process_read_buffer_cb, conn, NULL);
779   } else {
780   /* Otherwise, if there is no read watch, set one, so we can read
781    * more bytes */
782     ADD_WATCH(conn, G_IO_IN);
783   }
784 }
785 
786 
787 static void
conn_read_async_cb(GConn * conn)788 conn_read_async_cb (GConn* conn)
789 {
790   guint  bytes_to_read;
791   gchar* buffer_start;
792   GIOError error;
793   gsize  bytes_read;
794 
795   /* Resize the buffer if it's full. */
796   if (conn->length == conn->bytes_read)
797     {
798       conn->length *= 2;
799       conn->buffer = g_realloc(conn->buffer, conn->length);
800     }
801 
802   /* Calculate buffer start and length */
803   bytes_to_read = conn->length - conn->bytes_read;
804   buffer_start = &conn->buffer[conn->bytes_read];
805   g_return_if_fail (bytes_to_read > 0);
806 
807   /* Read data into buffer */
808   error = g_io_channel_read (conn->iochannel, buffer_start,
809 			     bytes_to_read, &bytes_read);
810 
811   /* Try again later if necessary */
812   if (error == G_IO_ERROR_AGAIN)
813     return;
814 
815   /* Fail if this is an error */
816   else if (error != G_IO_ERROR_NONE)
817     {
818       GConnEvent event = {GNET_CONN_ERROR, NULL, 0};
819 
820       ref_internal (conn);
821 
822       gnet_conn_disconnect (conn);
823       (conn->func) (conn, &event, conn->user_data);
824 
825       unref_internal (conn);
826 
827       return;
828     }
829 
830   /* If we read nothing, that means EOF and we're done.  We do not
831      callback with anything that might be in the buffer. */
832   else if (bytes_read == 0)
833     {
834       conn->read_eof = TRUE;
835     }
836 
837   /* Otherwise, we read something */
838   else
839     {
840       conn->bytes_read += bytes_read;
841     }
842 
843   /*** Process what we read *** */
844 
845   /* Process the read buffer */
846   ref_internal (conn);
847   do
848     {
849       /* Process data */
850       bytes_read = process_read_buffer (conn);
851       /* conn may be disconnected at this point */
852 
853       /* Stop if conn deleted */
854       if (conn->ref_count == 0)
855 	{
856 	  unref_internal (conn);
857 	  return;
858 	}
859 
860     } while (bytes_read > 0);
861 
862   unref_internal (conn);
863   /* conn is still good (though possibly disconnected).  Otherwise, we
864      would have returned in the do-loop. */
865 
866   /* Process EOF if:
867        - we read EOF
868        - the connection is still open
869        - there are reads in the read queue (we won't give the user
870            a CLOSE unless they make a read that triggers it.)
871   */
872   if (conn->read_eof && IS_CONNECTED(conn) && conn->read_queue)
873     {
874       GConnEvent event = {GNET_CONN_CLOSE, NULL, 0};
875 
876       /* (we know conn is still good - otherwise it would have been
877          deleted in the do-loop) */
878 
879       gnet_conn_disconnect (conn);
880       (conn->func) (conn, &event, conn->user_data);
881       return;	/* we're done with conn for now */
882     }
883 
884   /* Remove read watch if no more reads */
885   if (!conn->read_queue)
886     {
887       REMOVE_WATCH(conn, G_IO_IN);
888     }
889 }
890 
891 
892 
893 /* Called to dispatch reads to user callback */
894 static gboolean
process_read_buffer_cb(gpointer data)895 process_read_buffer_cb (gpointer data)
896 {
897   GConn* conn = (GConn*) data;
898   gint bytes_read;
899 
900   g_return_val_if_fail (conn, FALSE);
901 
902   conn->process_buffer_timeout = 0;
903 
904   /* Ignore if nothing to read */
905   if (conn->bytes_read == 0 || conn->read_queue == NULL)
906     return FALSE;
907 
908   /* Process reads */
909   ref_internal (conn);
910   do
911     {
912       /* Process data */
913       bytes_read = process_read_buffer (conn);
914       /* conn may be disconnected at this point */
915 
916       /* Stop if conn deleted */
917       if (conn->ref_count == 0)
918 	{
919 	  unref_internal (conn);
920 	  return FALSE;
921 	}
922     } while (bytes_read > 0);
923 
924   unref_internal (conn);
925   /* conn is still good (though possibly disconnected).  Otherwise, we
926      would have returned in the do-loop. */
927 
928   /* Process EOF (if we read EOF) and are still connected */
929   if (conn->read_eof && IS_CONNECTED(conn))
930     {
931       GConnEvent event = {GNET_CONN_CLOSE, NULL, 0};
932 
933       gnet_conn_disconnect (conn);
934       (conn->func) (conn, &event, conn->user_data);
935       return FALSE;	/* we're done with conn for now*/
936     }
937 
938   /* Set read watch if we're still connected and there's more to read */
939   if (IS_CONNECTED(conn) && conn->read_queue)
940     {
941       ADD_WATCH (conn, G_IO_IN);
942     }
943 
944   return FALSE;
945 }
946 
947 
948 /* Calculate number of bytes that can be processed by the top read */
949 static gint
bytes_processable(GConn * conn)950 bytes_processable (GConn* conn)
951 {
952   Read* read;
953 
954   g_return_val_if_fail (conn, 0);
955 
956   /* If there is no data to process or reads to process, return 0 */
957   if (conn->bytes_read == 0 || conn->read_queue == NULL)
958     return 0;
959 
960   /* Get a read off the queue */
961   read = (Read*) conn->read_queue->data;
962 
963   switch (read->mode)
964     {
965       /* Read any */
966     case 0:
967       {
968 	return conn->bytes_read;
969 	break;
970       }
971 
972       /* Read line */
973     case -1:
974       {
975 	guint i;
976 
977 	/* Look for \n, \r, or \r\n */
978 	for (i = 0; i < conn->bytes_read; ++i)
979 	  {
980 	    /* \n and \0  */
981 	    if (conn->buffer[i] == '\0' ||
982 		conn->buffer[i] == '\n')
983 	      return i+1;
984 
985 	    /* \r Only counted if we know the next character.  If
986 	       it's a \n, it'd need to be \0'ed out. */
987 	    else if (conn->buffer[i] == '\r' &&
988 		     ((i+1) < conn->bytes_read))
989 	      {
990 		if (conn->buffer[i+1] == '\n')
991 		  return i+2;
992 		else
993 		  return i+1;
994 	      }
995 	  }
996 	break;
997       }
998 
999     default:		/* Read n */
1000       {
1001 	if (conn->bytes_read >= read->mode)
1002 	  return read->mode;
1003 	break;
1004       }
1005     }
1006 
1007   return 0;
1008 }
1009 
1010 
1011 /* Return bytes read */
1012 static gint
process_read_buffer(GConn * conn)1013 process_read_buffer (GConn* conn)
1014 {
1015   Read* read;
1016   gint bytes_processed = 0;
1017   gint bytes_read = 0;
1018 
1019   g_return_val_if_fail (conn, FALSE);
1020 
1021   /* If there is no data to process or reads to process, return 0 */
1022   if (conn->bytes_read == 0 || conn->read_queue == NULL)
1023     return 0;
1024 
1025   /* Get a read off the queue */
1026   read = (Read*) conn->read_queue->data;
1027 
1028   ref_internal (conn);
1029 
1030   switch (read->mode)
1031     {
1032       /* Read any */
1033     case 0:
1034       {
1035 	bytes_processed = bytes_read = conn->bytes_read;
1036 
1037 	break;
1038       }
1039 
1040       /* Read line */
1041     case -1:
1042       {
1043 	guint i;
1044 
1045 	/* Look for \n, \r, or \r\n */
1046 	for (i = 0; i < conn->bytes_read; ++i)
1047 	  {
1048 	    /* \0  */
1049 	    if (conn->buffer[i] == '\0')
1050 	      {
1051 		bytes_processed = bytes_read = i + 1;
1052 		break;
1053 	      }
1054 
1055 	    /* \n */
1056 	    else if (conn->buffer[i] == '\n')
1057 	      {
1058 		conn->buffer[i] = '\0';
1059 		bytes_processed = bytes_read = i + 1;
1060 		break;
1061 	      }
1062 
1063 	    /* \r  Only counted if we know the next character.  If it's
1064 	       a \n, it needs to be \0'ed out. */
1065 	    else if (conn->buffer[i] == '\r' &&
1066 		     ((i+1) < conn->bytes_read))
1067 	      {
1068 		if (conn->buffer[i+1] == '\n')
1069 		  {
1070 		    conn->buffer[i] = '\0';
1071 		    conn->buffer[i+1] = '\0';
1072 		    bytes_read = i + 1;
1073 		    bytes_processed = i + 2;
1074 		  }
1075 		else
1076 		  {
1077 		    conn->buffer[i] = '\0';
1078 		    bytes_processed = bytes_read = i + 1;
1079 		  }
1080 		break;
1081 	      }
1082 	  }
1083 
1084 	break;
1085       }
1086 
1087     default:		/* Read n */
1088       {
1089 	if (conn->bytes_read >= read->mode)
1090 	  bytes_processed = bytes_read = read->mode;
1091 
1092 	break;
1093       }
1094     }
1095 
1096   if (bytes_read)
1097     {
1098       GConnEvent event;
1099 
1100       event.type = GNET_CONN_READ;
1101       event.buffer = conn->buffer;
1102       event.length = bytes_read;
1103 
1104       (conn->func) (conn, &event, conn->user_data);
1105     }
1106   /* Note: User may have disconnected after the callback */
1107 
1108   /* If read successful and we're still connected, move bytes over and
1109      remove read */
1110   if (bytes_processed && IS_CONNECTED(conn))
1111     {
1112       g_assert (conn->bytes_read >= bytes_processed);/* Sanity check */
1113 
1114       /* Move bytes over */
1115       g_memmove (conn->buffer, &conn->buffer[bytes_processed],
1116 		 conn->bytes_read - bytes_processed);
1117       conn->bytes_read -= bytes_processed;
1118 
1119       /* Remove read from queue */
1120       conn->read_queue = g_list_remove (conn->read_queue, read);
1121       g_free (read);
1122     }
1123 
1124   unref_internal (conn);
1125 
1126   return bytes_processed;
1127 }
1128 
1129 
1130 
1131 
1132 /* **************************************** */
1133 
1134 
1135 
1136 /**
1137  *  gnet_conn_write_direct
1138  *  @conn: a #GConn
1139  *  @buffer: buffer to write from
1140  *  @length: length of @buffer
1141  *  @buffer_destroy_cb: function to call when buffer is no longer needed
1142  *
1143  *  Sets up an asynchronous write to @conn from @buffer.  The buffer is
1144  *  created by the caller and will not be copied.  The caller needs to
1145  *  make sure the buffer stays valid until @buffer_destroy_cb is called.
1146  *  This function can be called again before the asynchronous write
1147  *  completes.  @buffer_destroy_cb may be %NULL.
1148  *
1149  **/
1150 void
gnet_conn_write_direct(GConn * conn,gchar * buffer,gint length,GDestroyNotify buffer_destroy_cb)1151 gnet_conn_write_direct (GConn* conn, gchar* buffer, gint length,
1152 			GDestroyNotify buffer_destroy_cb)
1153 {
1154   Write* write;
1155 
1156   g_return_if_fail (conn != NULL);
1157   g_return_if_fail (buffer != NULL);
1158   g_return_if_fail (length >= 0);
1159 
1160   if (length == 0)
1161     return;
1162 
1163   /* Add to queue */
1164   write = g_new0 (Write, 1);
1165   write->buffer = buffer;
1166   write->length = length;
1167   write->buffer_destroy_cb = buffer_destroy_cb;
1168   conn->write_queue = g_list_append (conn->write_queue, write);
1169 
1170   conn_check_write_queue (conn);
1171 }
1172 
1173 /**
1174  *  gnet_conn_write
1175  *  @conn: a #GConn
1176  *  @buffer: buffer to write from
1177  *  @length: length of @buffer
1178  *
1179  *  Sets up an asynchronous write to @conn from @buffer.  The buffer is
1180  *  copied, so it may be deleted by the caller.  This function can be
1181  *  called again before the asynchronous write completes.
1182  *
1183  **/
1184 void
gnet_conn_write(GConn * conn,gchar * buffer,gint length)1185 gnet_conn_write (GConn* conn, gchar* buffer, gint length)
1186 {
1187   gchar *copy;
1188 
1189   g_return_if_fail (conn != NULL);
1190   g_return_if_fail (buffer != NULL);
1191   g_return_if_fail (length >= 0);
1192 
1193   if (length == 0)
1194     return;
1195 
1196   copy = g_memdup (buffer, length);
1197   gnet_conn_write_direct (conn, copy, length, (GDestroyNotify) g_free);
1198 }
1199 
1200 
1201 static void
conn_check_write_queue(GConn * conn)1202 conn_check_write_queue (GConn* conn)
1203 {
1204   /* Ignore if we are unconnected or there is no writes */
1205   if (!IS_CONNECTED(conn) || !conn->write_queue)
1206     return;
1207 
1208   /* Ignore if we are already watching OUT */
1209   if (IS_WATCHING(conn, G_IO_OUT))
1210     return;
1211 
1212   /* Watch for write */
1213   ADD_WATCH (conn, G_IO_OUT);
1214 }
1215 
1216 
1217 static void
conn_write_async_cb(GConn * conn)1218 conn_write_async_cb (GConn* conn)
1219 {
1220   Write*     write;
1221   GIOError   error;
1222   guint      bytes_to_write;
1223   gchar*     buffer_start;
1224   gsize      bytes_written;
1225   GConnEvent event = {GNET_CONN_ERROR, NULL, 0};
1226 
1227   write = (Write*) conn->write_queue->data;
1228   g_return_if_fail (write != NULL);
1229 
1230   /* Calculate start of buffer */
1231   buffer_start = &write->buffer[conn->bytes_written];
1232   bytes_to_write = write->length - conn->bytes_written;
1233 
1234   /* Write */
1235   error = g_io_channel_write(conn->iochannel, buffer_start,
1236 			     bytes_to_write, &bytes_written);
1237 
1238   /* Check for error.  If error, disconnect and notify */
1239   if (error != G_IO_ERROR_NONE)
1240     {
1241       gnet_conn_disconnect (conn);
1242       (conn->func) (conn, &event, conn->user_data);
1243       /* conn may be deleted now */
1244       return;
1245     }
1246   /* Otherwise, write is good */
1247 
1248   /* Increment bytes written count */
1249   conn->bytes_written += bytes_written;
1250 
1251   /* Check if we're done writing this queued write */
1252   if (conn->bytes_written == write->length)
1253     {
1254       /* Remove and delete the queued write */
1255       conn->write_queue = g_list_remove (conn->write_queue, write);
1256       conn_write_free(write);
1257 
1258       conn->bytes_written = 0;
1259 
1260       /* Remove watch if there are no more queued writes */
1261       if (conn->write_queue == NULL)
1262 	REMOVE_WATCH (conn, G_IO_OUT);
1263 
1264       /* Notify */
1265       event.type = GNET_CONN_WRITE;
1266       (conn->func)(conn, &event, conn->user_data);
1267       /* conn may be disconnected or deleted now */
1268     }
1269 
1270   /* Otherwise, keep watching for output */
1271   return;
1272 }
1273 
1274 
1275 
1276 /* **************************************** */
1277 
1278 /**
1279  * gnet_conn_set_watch_error
1280  * @conn: a #GConn
1281  * @enable: enable the %GNET_CONN_READABLE event?
1282  *
1283  * Enables (or disables) the %GNET_CONN_ERROR event for a #GConn.  If
1284  * enabled, the %GNET_CONN_ERROR event occurs when an error occurs.
1285  * The @conn is disconnected before the callback is made.
1286  *
1287  **/
1288 void
gnet_conn_set_watch_error(GConn * conn,gboolean enable)1289 gnet_conn_set_watch_error (GConn* conn, gboolean enable)
1290 {
1291   g_return_if_fail (conn);
1292 
1293   if (enable)
1294     ADD_WATCH(conn, G_IO_ERR | G_IO_HUP | G_IO_NVAL);
1295   else
1296     REMOVE_WATCH(conn, G_IO_ERR | G_IO_HUP | G_IO_NVAL);
1297 }
1298 
1299 
1300 /**
1301  * gnet_conn_set_watch_readable
1302  * @conn: a #GConn
1303  * @enable: enable the %GNET_CONN_READABLE event?
1304  *
1305  * Enables (or disables) the %GNET_CONN_READABLE event for a #GConn.
1306  * If enabled, the %GNET_CONN_READABLE event occurs when data can be
1307  * read from the socket.  Read from the iochannel member of the @conn.
1308  * Do not enable this while using gnet_conn_read(), gnet_conn_readn(),
1309  * or gnet_conn_readline().
1310  *
1311  **/
1312 void
gnet_conn_set_watch_readable(GConn * conn,gboolean enable)1313 gnet_conn_set_watch_readable (GConn* conn, gboolean enable)
1314 {
1315   g_return_if_fail (conn);
1316   g_return_if_fail (conn->func);
1317 
1318   conn->watch_readable = enable;
1319   if (enable)
1320     ADD_WATCH (conn, G_IO_IN);
1321   else
1322     REMOVE_WATCH (conn, G_IO_IN);
1323 }
1324 
1325 
1326 /**
1327  * gnet_conn_set_watch_writable
1328  * @conn: a #GConn
1329  * @enable: enable the #GNET_CONN_WRITABLE event?
1330  *
1331  * Enables (or disables) the %GNET_CONN_WRITABLE event for a #GConn.
1332  * If enabled, the #GNET_CONN_WRITABLE event occurs when data can be
1333  * written to the socket.  Write to the iochannel member of the @conn.
1334  * Do not enable this while using gnet_conn_write().
1335  *
1336  **/
1337 void
gnet_conn_set_watch_writable(GConn * conn,gboolean enable)1338 gnet_conn_set_watch_writable (GConn* conn, gboolean enable)
1339 {
1340   g_return_if_fail (conn);
1341 
1342   conn->watch_writable = enable;
1343   if (enable)
1344     ADD_WATCH (conn, G_IO_OUT);
1345   else
1346     REMOVE_WATCH (conn, G_IO_OUT);
1347 }
1348 
1349 
1350 /* **************************************** */
1351 
1352 
1353 /**
1354  *  gnet_conn_timeout
1355  *  @conn: a #GConn
1356  *  @timeout: Timeout (in milliseconds)
1357  *
1358  *  Sets a timeout on a #GConn.  When the timer expires, the
1359  *  %GNET_CONN_STATUS_TIMEOUT event occurs.  If there already is a
1360  *  timeout set on @conn, the old timeout is canceled.  Set @timeout
1361  *  to 0 to cancel the current timeout.
1362  *
1363  **/
1364 void
gnet_conn_timeout(GConn * conn,guint timeout)1365 gnet_conn_timeout (GConn* conn, guint timeout)
1366 {
1367   g_return_if_fail (conn != NULL);
1368 
1369   if (conn->timer) {
1370     _gnet_source_remove (conn->context, conn->timer);
1371     conn->timer = 0;
1372   }
1373 
1374   if (timeout) {
1375     g_return_if_fail (conn->func != NULL);
1376     conn->timer = _gnet_timeout_add_full (conn->context, G_PRIORITY_DEFAULT,
1377         timeout, conn_timeout_cb, conn, (GDestroyNotify) NULL);
1378   }
1379 }
1380 
1381 
1382 static gboolean
conn_timeout_cb(gpointer data)1383 conn_timeout_cb (gpointer data)
1384 {
1385   GConn* conn = (GConn*) data;
1386   GConnEvent event;
1387 
1388   g_return_val_if_fail (conn, FALSE);
1389 
1390   conn->timer = 0;
1391 
1392   event.type = GNET_CONN_TIMEOUT;
1393   event.buffer = NULL;
1394   event.length = 0;
1395   (conn->func)(conn, &event, conn->user_data);
1396 
1397   return FALSE;
1398 }
1399