Fix compilation errors.
[platform/upstream/libsoup.git] / libsoup / soup-socket.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-socket.c: Socket networking code.
4  *
5  * Copyright (C) 2000-2003, Ximian, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <string.h>
16 #include <unistd.h>
17
18 #include "soup-address.h"
19 #include "soup-socket.h"
20 #include "soup-marshal.h"
21 #include "soup-misc.h"
22 #include "soup-ssl.h"
23
24 #include <sys/types.h>
25
26 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
27
28 enum {
29         CONNECT_RESULT,
30         READABLE,
31         WRITABLE,
32         DISCONNECTED,
33         NEW_CONNECTION,
34         LAST_SIGNAL
35 };
36
37 static guint signals[LAST_SIGNAL] = { 0 };
38
39 enum {
40         PROP_0,
41
42         PROP_NON_BLOCKING,
43         PROP_NODELAY,
44         PROP_REUSEADDR,
45         PROP_CLOEXEC,
46         PROP_IS_SERVER,
47         PROP_SSL_CREDENTIALS,
48
49         LAST_PROP
50 };
51
52 typedef struct {
53         int sockfd;
54         SoupAddress *local_addr, *remote_addr;
55         GIOChannel *iochannel;
56
57         guint non_blocking:1;
58         guint nodelay:1;
59         guint reuseaddr:1;
60         guint cloexec:1;
61         guint is_server:1;
62         gpointer ssl_creds;
63
64         guint           watch;
65         guint           read_tag, write_tag, error_tag;
66         GByteArray     *read_buf;
67
68         GMutex *iolock, *addrlock;
69 } SoupSocketPrivate;
70 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
71
72 #ifdef HAVE_IPV6
73 #define soup_sockaddr_max sockaddr_in6
74 #else
75 #define soup_sockaddr_max sockaddr_in
76 #endif
77
78 static void set_property (GObject *object, guint prop_id,
79                           const GValue *value, GParamSpec *pspec);
80 static void get_property (GObject *object, guint prop_id,
81                           GValue *value, GParamSpec *pspec);
82
83 #ifdef G_OS_WIN32
84 #define SOUP_CLOSE_SOCKET(socket) closesocket (socket)
85 #define SOUP_IS_SOCKET_ERROR(status) ((status) == SOCKET_ERROR)
86 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) == INVALID_SOCKET)
87 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (WSAGetLastError () == WSAEWOULDBLOCK)
88 #else
89 #define SOUP_CLOSE_SOCKET(socket) close (socket)
90 #define SOUP_IS_SOCKET_ERROR(status) ((status) == -1)
91 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) < 0)
92 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (errno == EINPROGRESS)
93 #endif
94
95 static void
96 soup_socket_init (SoupSocket *sock)
97 {
98         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
99
100         priv->sockfd = -1;
101         priv->non_blocking = priv->nodelay = TRUE;
102         priv->reuseaddr = TRUE;
103         priv->cloexec = FALSE;
104         priv->addrlock = g_mutex_new ();
105         priv->iolock = g_mutex_new ();
106 }
107
108 static void
109 disconnect_internal (SoupSocketPrivate *priv)
110 {
111         g_io_channel_unref (priv->iochannel);
112         priv->iochannel = NULL;
113         priv->sockfd = -1;
114
115         if (priv->read_tag) {
116                 g_source_remove (priv->read_tag);
117                 priv->read_tag = 0;
118         }
119         if (priv->write_tag) {
120                 g_source_remove (priv->write_tag);
121                 priv->write_tag = 0;
122         }
123         if (priv->error_tag) {
124                 g_source_remove (priv->error_tag);
125                 priv->error_tag = 0;
126         }
127 }
128
129 static void
130 finalize (GObject *object)
131 {
132         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
133
134         if (priv->iochannel)
135                 disconnect_internal (priv);
136
137         if (priv->local_addr)
138                 g_object_unref (priv->local_addr);
139         if (priv->remote_addr)
140                 g_object_unref (priv->remote_addr);
141
142         if (priv->watch)
143                 g_source_remove (priv->watch);
144
145         if (priv->read_buf)
146                 g_byte_array_free (priv->read_buf, TRUE);
147
148         g_mutex_free (priv->addrlock);
149         g_mutex_free (priv->iolock);
150
151         G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
152 }
153
154 static void
155 soup_socket_class_init (SoupSocketClass *socket_class)
156 {
157         GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
158
159         g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
160
161         /* virtual method override */
162         object_class->finalize = finalize;
163         object_class->set_property = set_property;
164         object_class->get_property = get_property;
165
166         /* signals */
167
168         /**
169          * SoupSocket::connect-result:
170          * @sock: the socket
171          * @status: the status
172          *
173          * Emitted when a connection attempt succeeds or fails. This
174          * is used internally by soup_socket_client_new_async().
175          **/
176         signals[CONNECT_RESULT] =
177                 g_signal_new ("connect_result",
178                               G_OBJECT_CLASS_TYPE (object_class),
179                               G_SIGNAL_RUN_FIRST,
180                               G_STRUCT_OFFSET (SoupSocketClass, connect_result),
181                               NULL, NULL,
182                               soup_marshal_NONE__INT,
183                               G_TYPE_NONE, 1,
184                               G_TYPE_INT);
185
186         /**
187          * SoupSocket::readable:
188          * @sock: the socket
189          *
190          * Emitted when an async socket is readable. See
191          * soup_socket_read() and soup_socket_read_until().
192          **/
193         signals[READABLE] =
194                 g_signal_new ("readable",
195                               G_OBJECT_CLASS_TYPE (object_class),
196                               G_SIGNAL_RUN_LAST,
197                               G_STRUCT_OFFSET (SoupSocketClass, readable),
198                               NULL, NULL,
199                               soup_marshal_NONE__NONE,
200                               G_TYPE_NONE, 0);
201
202         /**
203          * SoupSocket::writable:
204          * @sock: the socket
205          *
206          * Emitted when an async socket is writable. See
207          * soup_socket_write().
208          **/
209         signals[WRITABLE] =
210                 g_signal_new ("writable",
211                               G_OBJECT_CLASS_TYPE (object_class),
212                               G_SIGNAL_RUN_LAST,
213                               G_STRUCT_OFFSET (SoupSocketClass, writable),
214                               NULL, NULL,
215                               soup_marshal_NONE__NONE,
216                               G_TYPE_NONE, 0);
217
218         /**
219          * SoupSocket::disconnected:
220          * @sock: the socket
221          *
222          * Emitted when the socket is disconnected, for whatever
223          * reason.
224          **/
225         signals[DISCONNECTED] =
226                 g_signal_new ("disconnected",
227                               G_OBJECT_CLASS_TYPE (object_class),
228                               G_SIGNAL_RUN_LAST,
229                               G_STRUCT_OFFSET (SoupSocketClass, disconnected),
230                               NULL, NULL,
231                               soup_marshal_NONE__NONE,
232                               G_TYPE_NONE, 0);
233
234         /**
235          * SoupSocket::new-connection:
236          * @sock: the socket
237          * @new: the new socket
238          *
239          * Emitted when a listening socket (set up with
240          * soup_socket_listen() or soup_socket_server_new()) receives a
241          * new connection.
242          **/
243         signals[NEW_CONNECTION] =
244                 g_signal_new ("new_connection",
245                               G_OBJECT_CLASS_TYPE (object_class),
246                               G_SIGNAL_RUN_FIRST,
247                               G_STRUCT_OFFSET (SoupSocketClass, new_connection),
248                               NULL, NULL,
249                               soup_marshal_NONE__OBJECT,
250                               G_TYPE_NONE, 1,
251                               SOUP_TYPE_SOCKET);
252
253         /* properties */
254         g_object_class_install_property (
255                 object_class, PROP_NON_BLOCKING,
256                 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
257                                       "Non-blocking",
258                                       "Whether or not the socket uses non-blocking I/O",
259                                       TRUE,
260                                       G_PARAM_READWRITE));
261         g_object_class_install_property (
262                 object_class, PROP_NODELAY,
263                 g_param_spec_boolean (SOUP_SOCKET_FLAG_NODELAY,
264                                       "NODELAY",
265                                       "Whether or not the socket uses TCP NODELAY",
266                                       TRUE,
267                                       G_PARAM_READWRITE));
268         g_object_class_install_property (
269                 object_class, PROP_REUSEADDR,
270                 g_param_spec_boolean (SOUP_SOCKET_FLAG_REUSEADDR,
271                                       "REUSEADDR",
272                                       "Whether or not the socket uses the TCP REUSEADDR flag",
273                                       TRUE,
274                                       G_PARAM_READWRITE));
275         g_object_class_install_property (
276                 object_class, PROP_CLOEXEC,
277                 g_param_spec_boolean (SOUP_SOCKET_FLAG_CLOEXEC,
278                                       "CLOEXEC",
279                                       "Whether or not the socket will be closed automatically on exec()",
280                                       FALSE,
281                                       G_PARAM_READWRITE));
282         g_object_class_install_property (
283                 object_class, PROP_IS_SERVER,
284                 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
285                                       "Server",
286                                       "Whether or not the socket is a server socket",
287                                       FALSE,
288                                       G_PARAM_READABLE));
289         g_object_class_install_property (
290                 object_class, PROP_SSL_CREDENTIALS,
291                 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
292                                       "SSL credentials",
293                                       "SSL credential information, passed from the session to the SSL implementation",
294                                       G_PARAM_READWRITE));
295
296 #ifdef G_OS_WIN32
297         /* Make sure WSAStartup() gets called. */
298         soup_address_get_type ();
299 #endif
300 }
301
302
303 static void
304 update_fdflags (SoupSocketPrivate *priv)
305 {
306         int opt;
307 #ifndef G_OS_WIN32
308         int flags;
309 #endif
310
311         if (priv->sockfd == -1)
312                 return;
313
314 #ifndef G_OS_WIN32
315         flags = fcntl (priv->sockfd, F_GETFL, 0);
316         if (flags != -1) {
317                 if (priv->non_blocking)
318                         flags |= O_NONBLOCK;
319                 else
320                         flags &= ~O_NONBLOCK;
321                 fcntl (priv->sockfd, F_SETFL, flags);
322         }
323        flags = fcntl (priv->sockfd, F_GETFD, 0);
324        if (flags != -1) {
325                if (priv->cloexec)
326                        flags |= FD_CLOEXEC;
327                else
328                        flags &= ~FD_CLOEXEC;
329                fcntl (priv->sockfd, F_SETFD, flags);
330         }
331
332 #else
333         if (priv->non_blocking) {
334                 u_long val = 1;
335                 ioctlsocket (priv->sockfd, FIONBIO, &val);
336         } else {
337                 u_long val = 0;
338                 ioctlsocket (priv->sockfd, FIONBIO, &val);
339         }               
340 #endif
341
342         opt = (priv->nodelay != 0);
343         setsockopt (priv->sockfd, IPPROTO_TCP,
344                     TCP_NODELAY, (void *) &opt, sizeof (opt));
345
346         opt = (priv->reuseaddr != 0);
347         setsockopt (priv->sockfd, SOL_SOCKET,
348                     SO_REUSEADDR, (void *) &opt, sizeof (opt));
349 }
350
351 static void
352 set_property (GObject *object, guint prop_id,
353               const GValue *value, GParamSpec *pspec)
354 {
355         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
356
357         switch (prop_id) {
358         case PROP_NON_BLOCKING:
359                 priv->non_blocking = g_value_get_boolean (value);
360                 update_fdflags (priv);
361                 break;
362         case PROP_NODELAY:
363                 priv->nodelay = g_value_get_boolean (value);
364                 update_fdflags (priv);
365                 break;
366         case PROP_REUSEADDR:
367                 priv->reuseaddr = g_value_get_boolean (value);
368                 update_fdflags (priv);
369                 break;
370         case PROP_CLOEXEC:
371                 priv->cloexec = g_value_get_boolean (value);
372                 update_fdflags (priv);
373                 break;
374         case PROP_SSL_CREDENTIALS:
375                 priv->ssl_creds = g_value_get_pointer (value);
376                 break;
377         default:
378                 break;
379         }
380 }
381
382 static void
383 get_property (GObject *object, guint prop_id,
384               GValue *value, GParamSpec *pspec)
385 {
386         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
387
388         switch (prop_id) {
389         case PROP_NON_BLOCKING:
390                 g_value_set_boolean (value, priv->non_blocking);
391                 break;
392         case PROP_NODELAY:
393                 g_value_set_boolean (value, priv->nodelay);
394                 break;
395         case PROP_REUSEADDR:
396                 g_value_set_boolean (value, priv->reuseaddr);
397                 break;
398         case PROP_CLOEXEC:
399                 g_value_set_boolean (value, priv->cloexec);
400                 break;
401         case PROP_IS_SERVER:
402                 g_value_set_boolean (value, priv->is_server);
403                 break;
404         case PROP_SSL_CREDENTIALS:
405                 g_value_set_pointer (value, priv->ssl_creds);
406                 break;
407         default:
408                 break;
409         }
410 }
411
412
413 /**
414  * soup_socket_new:
415  * @optname1: name of first property to set (or %NULL)
416  * @...: value of @optname1, followed by additional property/value pairs
417  *
418  * Creates a new (disconnected) socket
419  *
420  * Return value: the new socket
421  **/
422 SoupSocket *
423 soup_socket_new (const char *optname1, ...)
424 {
425         SoupSocket *sock;
426         va_list ap;
427
428         va_start (ap, optname1);
429         sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
430                                                   optname1, ap);
431         va_end (ap);
432
433         return sock;
434 }
435
436 static GIOChannel *
437 get_iochannel (SoupSocketPrivate *priv)
438 {
439         g_mutex_lock (priv->iolock);
440         if (!priv->iochannel) {
441 #ifndef G_OS_WIN32
442                 priv->iochannel =
443                         g_io_channel_unix_new (priv->sockfd);
444 #else
445                 priv->iochannel =
446                         g_io_channel_win32_new_socket (priv->sockfd);
447 #endif
448                 g_io_channel_set_close_on_unref (priv->iochannel, TRUE);
449                 g_io_channel_set_encoding (priv->iochannel, NULL, NULL);
450                 g_io_channel_set_buffered (priv->iochannel, FALSE);
451         }
452         g_mutex_unlock (priv->iolock);
453         return priv->iochannel;
454 }
455
456 static gboolean
457 idle_connect_result (gpointer user_data)
458 {
459         SoupSocket *sock = user_data;
460         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
461
462         priv->watch = 0;
463
464         g_signal_emit (sock, signals[CONNECT_RESULT], 0,
465                        priv->sockfd != -1 ? SOUP_STATUS_OK : SOUP_STATUS_CANT_CONNECT);
466         return FALSE;
467 }
468
469 static gboolean
470 connect_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
471 {
472         SoupSocket *sock = data;
473         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
474         int error = 0;
475         int len = sizeof (error);
476
477         /* Remove the watch now in case we don't return immediately */
478         g_source_remove (priv->watch);
479         priv->watch = 0;
480
481         if (condition & ~(G_IO_IN | G_IO_OUT))
482                 goto cant_connect;
483
484         if (getsockopt (priv->sockfd, SOL_SOCKET, SO_ERROR,
485                         (void *) &error, &len) != 0)
486                 goto cant_connect;
487         if (error)
488                 goto cant_connect;
489
490         return idle_connect_result (sock);
491
492  cant_connect:
493         g_signal_emit (sock, signals[CONNECT_RESULT], 0, SOUP_STATUS_CANT_CONNECT);
494         return FALSE;
495 }
496
497 static void
498 got_address (SoupAddress *addr, guint status, gpointer user_data)
499 {
500         SoupSocket *sock = user_data;
501         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
502
503         if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
504                 g_signal_emit (sock, signals[CONNECT_RESULT], 0, status);
505                 g_object_unref (sock);
506                 return;
507         }
508
509         soup_socket_connect (sock, priv->remote_addr);
510         /* soup_socket_connect re-reffed addr */
511         g_object_unref (addr);
512
513         g_object_unref (sock);
514 }
515
516 /**
517  * soup_socket_connect:
518  * @sock: a client #SoupSocket (which must not already be connected)
519  * @remote_addr: address to connect to
520  *
521  * If %SOUP_SOCKET_FLAG_NONBLOCKING has been set on the socket, this
522  * begins asynchronously connecting to the given address. The socket
523  * will emit %connect_result when it succeeds or fails (but not before
524  * returning from this function).
525  *
526  * If %SOUP_SOCKET_FLAG_NONBLOCKING has not been set, this will
527  * attempt to synchronously connect.
528  *
529  * Return value: %SOUP_STATUS_CONTINUE if connecting asynchronously,
530  * otherwise a success or failure code.
531  **/
532 guint
533 soup_socket_connect (SoupSocket *sock, SoupAddress *remote_addr)
534 {
535         SoupSocketPrivate *priv;
536         struct sockaddr *sa;
537         int len, status;
538
539         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
540         priv = SOUP_SOCKET_GET_PRIVATE (sock);
541         g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
542         g_return_val_if_fail (priv->sockfd == -1, SOUP_STATUS_MALFORMED);
543         g_return_val_if_fail (SOUP_IS_ADDRESS (remote_addr), SOUP_STATUS_MALFORMED);
544
545         priv->remote_addr = g_object_ref (remote_addr);
546         if (!priv->non_blocking) {
547                 status = soup_address_resolve_sync (remote_addr);
548                 if (!SOUP_STATUS_IS_SUCCESSFUL (status))
549                         return status;
550         }
551
552         sa = soup_address_get_sockaddr (priv->remote_addr, &len);
553         if (!sa) {
554                 if (!priv->non_blocking)
555                         return SOUP_STATUS_CANT_RESOLVE;
556
557                 g_object_ref (sock);
558                 soup_address_resolve_async (remote_addr, got_address, sock);
559                 return SOUP_STATUS_CONTINUE;
560         }
561
562         priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
563         if (SOUP_IS_INVALID_SOCKET (priv->sockfd)) {
564                 goto done;
565         }
566         update_fdflags (priv);
567
568         status = connect (priv->sockfd, sa, len);
569
570         if (SOUP_IS_SOCKET_ERROR (status)) {
571                 if (SOUP_IS_CONNECT_STATUS_INPROGRESS ()) {
572                         /* Wait for connect to succeed or fail */
573                         priv->watch =
574                                 g_io_add_watch (get_iochannel (priv),
575                                                 G_IO_IN | G_IO_OUT |
576                                                 G_IO_PRI | G_IO_ERR |
577                                                 G_IO_HUP | G_IO_NVAL,
578                                                 connect_watch, sock);
579                         return SOUP_STATUS_CONTINUE;
580                 } else {
581                         SOUP_CLOSE_SOCKET (priv->sockfd);
582                         priv->sockfd = -1;
583                 }
584         } else
585                 get_iochannel (priv);
586
587  done:
588         if (priv->non_blocking) {
589                 priv->watch = g_idle_add (idle_connect_result, sock);
590                 return SOUP_STATUS_CONTINUE;
591         } else if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
592                 return SOUP_STATUS_CANT_CONNECT;
593         else
594                 return SOUP_STATUS_OK;
595 }
596
597 static gboolean
598 listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
599 {
600         SoupSocket *sock = data, *new;
601         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
602         struct soup_sockaddr_max sa;
603         int sa_len, sockfd;
604
605         if (condition & (G_IO_HUP | G_IO_ERR)) {
606                 g_source_remove (priv->watch);
607                 priv->watch = 0;
608                 return FALSE;
609         }
610
611         sa_len = sizeof (sa);
612         sockfd = accept (priv->sockfd, (struct sockaddr *)&sa, &sa_len);
613         if (SOUP_IS_INVALID_SOCKET (sockfd))
614                 return TRUE;
615
616         new = g_object_new (SOUP_TYPE_SOCKET, NULL);
617         new_priv = SOUP_SOCKET_GET_PRIVATE (new);
618         new_priv->sockfd = sockfd;
619         new_priv->non_blocking = priv->non_blocking;
620         new_priv->nodelay = priv->nodelay;
621         new_priv->is_server = TRUE;
622         new_priv->ssl_creds = priv->ssl_creds;
623         update_fdflags (new_priv);
624
625         new_priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
626
627         if (new_priv->ssl_creds) {
628                 if (!soup_socket_start_ssl (new)) {
629                         g_object_unref (new);
630                         return TRUE;
631                 }
632         } else
633                 get_iochannel (new_priv);
634
635         g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
636         g_object_unref (new);
637
638         return TRUE;
639 }
640
641 /**
642  * soup_socket_listen:
643  * @sock: a server #SoupSocket (which must not already be connected or
644  * listening)
645  * @local_addr: Local address to bind to.
646  *
647  * Makes @sock start listening on the given interface and port. When
648  * connections come in, @sock will emit %new_connection.
649  *
650  * Return value: whether or not @sock is now listening.
651  **/
652 gboolean
653 soup_socket_listen (SoupSocket *sock, SoupAddress *local_addr)
654 {
655         SoupSocketPrivate *priv;
656         struct sockaddr *sa;
657         int sa_len;
658
659         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
660         priv = SOUP_SOCKET_GET_PRIVATE (sock);
661         g_return_val_if_fail (priv->is_server, FALSE);
662         g_return_val_if_fail (priv->sockfd == -1, FALSE);
663         g_return_val_if_fail (SOUP_IS_ADDRESS (local_addr), FALSE);
664
665         /* @local_addr may have its port set to 0. So we intentionally
666          * don't store it in priv->local_addr, so that if the
667          * caller calls soup_socket_get_local_address() later, we'll
668          * have to make a new addr by calling getsockname(), which
669          * will have the right port number.
670          */
671         sa = soup_address_get_sockaddr (local_addr, &sa_len);
672         g_return_val_if_fail (sa != NULL, FALSE);
673
674         priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
675         if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
676                 goto cant_listen;
677         update_fdflags (priv);
678
679         /* Bind */
680         if (bind (priv->sockfd, sa, sa_len) != 0)
681                 goto cant_listen;
682
683         /* Listen */
684         if (listen (priv->sockfd, 10) != 0)
685                 goto cant_listen;
686
687         priv->watch = g_io_add_watch (get_iochannel (priv),
688                                       G_IO_IN | G_IO_ERR | G_IO_HUP,
689                                       listen_watch, sock);
690         return TRUE;
691
692  cant_listen:
693         if (priv->sockfd != -1) {
694                 SOUP_CLOSE_SOCKET (priv->sockfd);
695                 priv->sockfd = -1;
696         }
697
698         return FALSE;
699 }
700
701 /**
702  * soup_socket_start_ssl:
703  * @sock: the socket
704  *
705  * Starts using SSL on @socket.
706  *
707  * Return value: success or failure
708  **/
709 gboolean
710 soup_socket_start_ssl (SoupSocket *sock)
711 {
712         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
713
714         return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr));
715 }
716         
717 /**
718  * soup_socket_start_proxy_ssl:
719  * @sock: the socket
720  * @ssl_host: hostname of the SSL server
721  *
722  * Starts using SSL on @socket, expecting to find a host named
723  * @ssl_host.
724  *
725  * Return value: success or failure
726  **/
727 gboolean
728 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host)
729 {
730         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
731         GIOChannel *ssl_chan;
732
733         get_iochannel (priv);
734         ssl_chan = soup_ssl_wrap_iochannel (
735                 priv->iochannel, priv->is_server ?
736                 SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
737                 ssl_host, priv->ssl_creds);
738
739         if (!ssl_chan)
740                 return FALSE;
741
742         priv->iochannel = ssl_chan;
743         return TRUE;
744 }
745         
746
747 /**
748  * soup_socket_client_new_async:
749  * @hostname: remote machine to connect to
750  * @port: remote port to connect to
751  * @ssl_creds: SSL credentials structure, or %NULL if not SSL
752  * @callback: callback to call when the socket is connected
753  * @user_data: data for @callback
754  *
755  * Creates a connection to @hostname and @port. @callback will be
756  * called when the connection completes (or fails).
757  *
758  * Return value: the new socket (not yet ready for use).
759  **/
760 SoupSocket *
761 soup_socket_client_new_async (const char *hostname, guint port,
762                               gpointer ssl_creds,
763                               SoupSocketCallback callback, gpointer user_data)
764 {
765         SoupSocket *sock;
766
767         g_return_val_if_fail (hostname != NULL, NULL);
768
769         sock = g_object_new (SOUP_TYPE_SOCKET,
770                              SOUP_SOCKET_SSL_CREDENTIALS, ssl_creds,
771                              NULL);
772         soup_socket_connect (sock, soup_address_new (hostname, port));
773
774         if (callback) {
775                 soup_signal_connect_once (sock, "connect_result",
776                                           G_CALLBACK (callback), user_data);
777         }
778         return sock;
779 }
780
781 /**
782  * soup_socket_client_new_sync:
783  * @hostname: remote machine to connect to
784  * @port: remote port to connect to
785  * @ssl_creds: SSL credentials structure, or %NULL if not SSL
786  * @status_ret: pointer to return the soup status in
787  *
788  * Creates a connection to @hostname and @port. If @status_ret is not
789  * %NULL, it will contain a status code on return.
790  *
791  * Return value: the new socket, or %NULL if it could not connect.
792  **/
793 SoupSocket *
794 soup_socket_client_new_sync (const char *hostname, guint port,
795                              gpointer ssl_creds, guint *status_ret)
796 {
797         SoupSocket *sock;
798         SoupSocketPrivate *priv;
799         guint status;
800
801         g_return_val_if_fail (hostname != NULL, NULL);
802
803         sock = g_object_new (SOUP_TYPE_SOCKET,
804                              SOUP_SOCKET_SSL_CREDENTIALS, ssl_creds,
805                              NULL);
806         priv = SOUP_SOCKET_GET_PRIVATE (sock);
807         priv->non_blocking = FALSE;
808         status = soup_socket_connect (sock, soup_address_new (hostname, port));
809
810         if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
811                 g_object_unref (sock);
812                 sock = NULL;
813         }
814
815         if (status_ret)
816                 *status_ret = status;
817         return sock;
818 }
819
820 /**
821  * soup_socket_server_new:
822  * @local_addr: Local address to bind to. (Use soup_address_any_new() to
823  * accept connections on any local address)
824  * @ssl_creds: SSL credentials, or %NULL if this is not an SSL server
825  * @callback: Callback to call when a client connects
826  * @user_data: data to pass to @callback.
827  *
828  * Create and open a new #SoupSocket listening on the specified
829  * address. @callback will be called each time a client connects,
830  * with a new #SoupSocket.
831  *
832  * Returns: a new #SoupSocket, or NULL if there was a failure.
833  **/
834 SoupSocket *
835 soup_socket_server_new (SoupAddress *local_addr, gpointer ssl_creds,
836                         SoupSocketListenerCallback callback,
837                         gpointer user_data)
838 {
839         SoupSocket *sock;
840         SoupSocketPrivate *priv;
841
842         g_return_val_if_fail (SOUP_IS_ADDRESS (local_addr), NULL);
843
844         sock = g_object_new (SOUP_TYPE_SOCKET,
845                              SOUP_SOCKET_SSL_CREDENTIALS, ssl_creds,
846                              NULL);
847         priv = SOUP_SOCKET_GET_PRIVATE (sock);
848         priv->is_server = TRUE;
849         if (!soup_socket_listen (sock, local_addr)) {
850                 g_object_unref (sock);
851                 return NULL;
852         }
853
854         if (callback) {
855                 g_signal_connect (sock, "new_connection",
856                                   G_CALLBACK (callback), user_data);
857         }
858
859         return sock;
860 }
861
862
863 /**
864  * soup_socket_disconnect:
865  * @sock: a #SoupSocket
866  *
867  * Disconnects @sock. Any further read or write attempts on it will
868  * fail.
869  **/
870 void
871 soup_socket_disconnect (SoupSocket *sock)
872 {
873         SoupSocketPrivate *priv;
874         gboolean already_disconnected = FALSE;
875
876         g_return_if_fail (SOUP_IS_SOCKET (sock));
877         priv = SOUP_SOCKET_GET_PRIVATE (sock);
878
879         if (g_mutex_trylock (priv->iolock)) {
880                 if (priv->iochannel)
881                         disconnect_internal (priv);
882                 else
883                         already_disconnected = TRUE;
884                 g_mutex_unlock (priv->iolock);
885         } else {
886                 int sockfd;
887
888                 /* Another thread is currently doing IO, so
889                  * we can't close the iochannel. So just kick
890                  * the file descriptor out from under it.
891                  */
892
893                 sockfd = priv->sockfd;
894                 priv->sockfd = -1;
895                 if (sockfd == -1)
896                         already_disconnected = TRUE;
897                 else {
898                         g_io_channel_set_close_on_unref (priv->iochannel,
899                                                          FALSE);
900                         SOUP_CLOSE_SOCKET (sockfd);
901                 }
902         }
903
904         if (already_disconnected)
905                 return;
906
907         /* Give all readers a chance to notice the connection close */
908         g_signal_emit (sock, signals[READABLE], 0);
909
910         /* FIXME: can't disconnect until all data is read */
911
912         /* Then let everyone know we're disconnected */
913         g_signal_emit (sock, signals[DISCONNECTED], 0);
914 }
915
916 /**
917  * soup_socket_is_connected:
918  * @sock: a #SoupSocket
919  *
920  * Tests if @sock is connected to another host
921  *
922  * Return value: %TRUE or %FALSE.
923  **/
924 gboolean
925 soup_socket_is_connected (SoupSocket *sock)
926 {
927         SoupSocketPrivate *priv;
928
929         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
930         priv = SOUP_SOCKET_GET_PRIVATE (sock);
931
932         return priv->iochannel != NULL;
933 }
934
935 /**
936  * soup_socket_get_local_address:
937  * @sock: a #SoupSocket
938  *
939  * Returns the #SoupAddress corresponding to the local end of @sock.
940  *
941  * Return value: the #SoupAddress
942  **/
943 SoupAddress *
944 soup_socket_get_local_address (SoupSocket *sock)
945 {
946         SoupSocketPrivate *priv;
947
948         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
949         priv = SOUP_SOCKET_GET_PRIVATE (sock);
950
951         g_mutex_lock (priv->addrlock);
952         if (!priv->local_addr) {
953                 struct soup_sockaddr_max bound_sa;
954                 int sa_len;
955
956                 sa_len = sizeof (bound_sa);
957                 getsockname (priv->sockfd, (struct sockaddr *)&bound_sa, &sa_len);
958                 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
959         }
960         g_mutex_unlock (priv->addrlock);
961
962         return priv->local_addr;
963 }
964
965 /**
966  * soup_socket_get_remote_address:
967  * @sock: a #SoupSocket
968  *
969  * Returns the #SoupAddress corresponding to the remote end of @sock.
970  *
971  * Return value: the #SoupAddress
972  **/
973 SoupAddress *
974 soup_socket_get_remote_address (SoupSocket *sock)
975 {
976         SoupSocketPrivate *priv;
977
978         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
979         priv = SOUP_SOCKET_GET_PRIVATE (sock);
980
981         g_mutex_lock (priv->addrlock);
982         if (!priv->remote_addr) {
983                 struct soup_sockaddr_max bound_sa;
984                 int sa_len;
985
986                 sa_len = sizeof (bound_sa);
987                 getpeername (priv->sockfd, (struct sockaddr *)&bound_sa, &sa_len);
988                 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
989         }
990         g_mutex_unlock (priv->addrlock);
991
992         return priv->remote_addr;
993 }
994
995
996
997
998 static gboolean
999 socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1000 {
1001         SoupSocket *sock = user_data;
1002         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1003
1004         priv->read_tag = 0;
1005         g_signal_emit (sock, signals[READABLE], 0);
1006
1007         return FALSE;
1008 }
1009
1010 static SoupSocketIOStatus
1011 read_from_network (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1012 {
1013         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1014         GIOStatus status;
1015         GIOCondition cond = G_IO_IN;
1016         GError *err = NULL;
1017
1018         if (!priv->iochannel) 
1019                 return SOUP_SOCKET_EOF;
1020
1021         status = g_io_channel_read_chars (priv->iochannel,
1022                                           buffer, len, nread, &err);
1023         if (err) {
1024                 if (err->domain == SOUP_SSL_ERROR &&
1025                     err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE)
1026                         cond = G_IO_OUT;
1027                 g_object_set_data_full (G_OBJECT (sock),
1028                                         "SoupSocket-last_error",
1029                                         err, (GDestroyNotify)g_error_free);
1030         } else {
1031                 g_object_set_data (G_OBJECT (sock),
1032                                    "SoupSocket-last_error",
1033                                    NULL);
1034         }
1035
1036         switch (status) {
1037         case G_IO_STATUS_NORMAL:
1038         case G_IO_STATUS_AGAIN:
1039                 if (*nread > 0)
1040                         return SOUP_SOCKET_OK;
1041
1042                 if (!priv->read_tag) {
1043                         priv->read_tag =
1044                                 g_io_add_watch (priv->iochannel, cond,
1045                                                 socket_read_watch, sock);
1046                 }
1047                 return SOUP_SOCKET_WOULD_BLOCK;
1048
1049         case G_IO_STATUS_EOF:
1050                 return SOUP_SOCKET_EOF;
1051
1052         default:
1053                 return SOUP_SOCKET_ERROR;
1054         }
1055 }
1056
1057 static SoupSocketIOStatus
1058 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1059 {
1060         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1061         GByteArray *read_buf = priv->read_buf;
1062
1063         *nread = MIN (read_buf->len, len);
1064         memcpy (buffer, read_buf->data, *nread);
1065
1066         if (*nread == read_buf->len) {
1067                 g_byte_array_free (read_buf, TRUE);
1068                 priv->read_buf = NULL;
1069         } else {
1070                 memmove (read_buf->data, read_buf->data + *nread, 
1071                          read_buf->len - *nread);
1072                 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1073         }
1074
1075         return SOUP_SOCKET_OK;
1076 }
1077
1078 /**
1079  * soup_socket_read:
1080  * @sock: the socket
1081  * @buffer: buffer to read into
1082  * @len: size of @buffer in bytes
1083  * @nread: on return, the number of bytes read into @buffer
1084  *
1085  * Attempts to read up to @len bytes from @sock into @buffer. If some
1086  * data is successfully read, soup_socket_read() will return
1087  * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1088  * actually read.
1089  *
1090  * If @sock is non-blocking, and no data is available, the return
1091  * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1092  * can connect to the %readable signal to know when there is more data
1093  * to read. (NB: You MUST read all available data off the socket
1094  * first. The %readable signal will only be emitted after
1095  * soup_socket_read() has returned %SOUP_SOCKET_WOULD_BLOCK.)
1096  *
1097  * Return value: a #SoupSocketIOStatus, as described above (or
1098  * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1099  * %SOUP_SOCKET_ERROR on any other error).
1100  **/
1101 SoupSocketIOStatus
1102 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1103 {
1104         SoupSocketPrivate *priv;
1105         SoupSocketIOStatus status;
1106
1107         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1108         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1109
1110         g_mutex_lock (priv->iolock);
1111         if (priv->read_buf)
1112                 status = read_from_buf (sock, buffer, len, nread);
1113         else
1114                 status = read_from_network (sock, buffer, len, nread);
1115         g_mutex_unlock (priv->iolock);
1116
1117         return status;
1118 }
1119
1120 /**
1121  * soup_socket_read_until:
1122  * @sock: the socket
1123  * @buffer: buffer to read into
1124  * @len: size of @buffer in bytes
1125  * @boundary: boundary to read until
1126  * @boundary_len: length of @boundary in bytes
1127  * @nread: on return, the number of bytes read into @buffer
1128  * @got_boundary: on return, whether or not the data in @buffer
1129  * ends with the boundary string
1130  *
1131  * Like soup_socket_read(), but reads no further than the first
1132  * occurrence of @boundary. (If the boundary is found, it will be
1133  * included in the returned data, and *@got_boundary will be set to
1134  * %TRUE.) Any data after the boundary will returned in future reads.
1135  *
1136  * Return value: as for soup_socket_read()
1137  **/
1138 SoupSocketIOStatus
1139 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1140                         gconstpointer boundary, gsize boundary_len,
1141                         gsize *nread, gboolean *got_boundary)
1142 {
1143         SoupSocketPrivate *priv;
1144         SoupSocketIOStatus status;
1145         GByteArray *read_buf;
1146         guint match_len, prev_len;
1147         guint8 *p, *end;
1148
1149         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1150         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1151         g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1152
1153         g_mutex_lock (priv->iolock);
1154
1155         *got_boundary = FALSE;
1156
1157         if (!priv->read_buf)
1158                 priv->read_buf = g_byte_array_new ();
1159         read_buf = priv->read_buf;
1160
1161         if (read_buf->len < boundary_len) {
1162                 prev_len = read_buf->len;
1163                 g_byte_array_set_size (read_buf, len);
1164                 status = read_from_network (sock,
1165                                             read_buf->data + prev_len,
1166                                             len - prev_len, nread);
1167                 read_buf->len = prev_len + *nread;
1168
1169                 if (status != SOUP_SOCKET_OK) {
1170                         g_mutex_unlock (priv->iolock);
1171                         return status;
1172                 }
1173         }
1174
1175         /* Scan for the boundary */
1176         end = read_buf->data + read_buf->len;
1177         for (p = read_buf->data; p <= end - boundary_len; p++) {
1178                 if (!memcmp (p, boundary, boundary_len)) {
1179                         p += boundary_len;
1180                         *got_boundary = TRUE;
1181                         break;
1182                 }
1183         }
1184
1185         /* Return everything up to 'p' (which is either just after the
1186          * boundary, or @boundary_len - 1 bytes before the end of the
1187          * buffer).
1188          */
1189         match_len = p - read_buf->data;
1190         status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1191
1192         g_mutex_unlock (priv->iolock);
1193         return status;
1194 }
1195
1196 static gboolean
1197 socket_write_watch (GIOChannel *chan, GIOCondition condition, gpointer user_data)
1198 {
1199         SoupSocket *sock = user_data;
1200         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1201
1202         priv->write_tag = 0;
1203         g_signal_emit (sock, signals[WRITABLE], 0);
1204
1205         return FALSE;
1206 }
1207
1208 /**
1209  * soup_socket_write:
1210  * @sock: the socket
1211  * @buffer: data to write
1212  * @len: size of @buffer, in bytes
1213  * @nwrote: on return, number of bytes written
1214  *
1215  * Attempts to write @len bytes from @buffer to @sock. If some data is
1216  * successfully written, the resturn status will be
1217  * %SOUP_SOCKET_SUCCESS, and *@nwrote will contain the number of bytes
1218  * actually written.
1219  *
1220  * If @sock is non-blocking, and no data could be written right away,
1221  * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1222  * the caller can connect to the %writable signal to know when more
1223  * data can be written. (NB: %writable is only emitted after a
1224  * %SOUP_SOCKET_WOULD_BLOCK.)
1225  *
1226  * Return value: a #SoupSocketIOStatus, as described above (or
1227  * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR).
1228  **/
1229 SoupSocketIOStatus
1230 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1231                    gsize len, gsize *nwrote)
1232 {
1233         SoupSocketPrivate *priv;
1234         GIOStatus status;
1235 #ifdef SIGPIPE
1236         gpointer pipe_handler;
1237 #endif
1238         GIOCondition cond = G_IO_OUT;
1239         GError *err = NULL;
1240
1241         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1242         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1243
1244         g_mutex_lock (priv->iolock);
1245
1246         if (!priv->iochannel) {
1247                 g_mutex_unlock (priv->iolock);
1248                 return SOUP_SOCKET_EOF;
1249         }
1250         if (priv->write_tag) {
1251                 g_mutex_unlock (priv->iolock);
1252                 return SOUP_SOCKET_WOULD_BLOCK;
1253         }
1254
1255 #ifdef SIGPIPE
1256         pipe_handler = signal (SIGPIPE, SIG_IGN);
1257 #endif
1258         status = g_io_channel_write_chars (priv->iochannel,
1259                                            buffer, len, nwrote, &err);
1260 #ifdef SIGPIPE
1261         signal (SIGPIPE, pipe_handler);
1262 #endif
1263         if (err) {
1264                 if (err->domain == SOUP_SSL_ERROR &&
1265                     err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ)
1266                         cond = G_IO_IN;
1267                 g_object_set_data_full (G_OBJECT (sock),
1268                                         "SoupSocket-last_error",
1269                                         err, (GDestroyNotify)g_error_free);
1270         } else {
1271                 g_object_set_data (G_OBJECT (sock),
1272                                    "SoupSocket-last_error",
1273                                    NULL);
1274         }
1275
1276         if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN) {
1277                 g_mutex_unlock (priv->iolock);
1278                 return SOUP_SOCKET_ERROR;
1279         }
1280
1281         if (*nwrote) {
1282                 g_mutex_unlock (priv->iolock);
1283                 return SOUP_SOCKET_OK;
1284         }
1285
1286         priv->write_tag =
1287                 g_io_add_watch (priv->iochannel, cond, 
1288                                 socket_write_watch, sock);
1289         g_mutex_unlock (priv->iolock);
1290         return SOUP_SOCKET_WOULD_BLOCK;
1291 }