autotools are dumb, so I'm also adding gnioenumtypes.{c,h}
[cascardo/gnio.git] / gnio / gsocket.c
1 /* GNIO - GLib Network Layer of GIO
2  *
3  * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Christian Kellner <gicmo@gnome.org>
21  *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
22  */
23
24 #include <config.h>
25 #include <glib.h>
26 #include <gio/gio.h>
27 #include <gnio/gnio.h>
28 #include "gasynchelper.h"
29 #include "gnioenumtypes.h"
30
31 #include <string.h>
32 #ifndef G_OS_WIN32
33 # include <netinet/in.h>
34 # include <arpa/inet.h>
35 # include <netdb.h>
36 # include <fcntl.h>
37 # include <unistd.h>
38 # include <sys/types.h>
39 #else
40
41 #endif
42 #include <errno.h>
43
44 #include "ginetaddress.h"
45 #include "ginet4address.h"
46 #include "ginet6address.h"
47 #include "gsocket.h"
48 #include "gnioerror.h"
49 #include "ginetsocketaddress.h"
50
51 G_DEFINE_TYPE (GSocket, g_socket, G_TYPE_OBJECT);
52
53 enum
54 {
55   PROP_0,
56   PROP_DOMAIN,
57   PROP_TYPE,
58   PROP_PROTOCOL,
59   PROP_FD,
60   PROP_BLOCKING,
61   PROP_BACKLOG,
62   PROP_REUSE_ADDRESS,
63   PROP_LOCAL_ADDRESS,
64   PROP_REMOTE_ADDRESS
65 };
66
67 struct _GSocketPrivate
68 {
69   GSocketDomain domain;
70   GSocketType type;
71   gchar *protocol;
72   gint fd;
73   gboolean blocking;
74   gint backlog;
75   gboolean reuse_address;
76   GError *error;
77   GSocketAddress *local_address;
78   GSocketAddress *remote_address;
79 };
80
81 static void
82 g_socket_constructed (GObject *object)
83 {
84
85 }
86
87 static void
88 g_socket_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
89 {
90   GSocket *socket = G_SOCKET (object);
91
92   switch (prop_id)
93     {
94       case PROP_DOMAIN:
95         g_value_set_int (value, socket->priv->domain);
96         break;
97
98       case PROP_TYPE:
99         g_value_set_int (value, socket->priv->type);
100         break;
101
102       case PROP_PROTOCOL:
103         g_value_set_string (value, socket->priv->protocol);
104         break;
105
106       case PROP_FD:
107         g_value_set_int (value, socket->priv->fd);
108         break;
109
110       case PROP_BLOCKING:
111         g_value_set_boolean (value, socket->priv->blocking);
112         break;
113
114       case PROP_BACKLOG:
115         g_value_set_int (value, socket->priv->backlog);
116         break;
117
118       case PROP_REUSE_ADDRESS:
119         g_value_set_boolean (value, socket->priv->reuse_address);
120         break;
121
122       case PROP_LOCAL_ADDRESS:
123         g_value_set_object (value, socket->priv->local_address);
124         break;
125
126       case PROP_REMOTE_ADDRESS:
127         g_value_set_object (value, socket->priv->remote_address);
128         break;
129
130       default:
131         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
132     }
133 }
134
135 static void
136 g_socket_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
137 {
138   GSocket *socket = G_SOCKET (object);
139
140   switch (prop_id)
141     {
142       case PROP_FD:
143         socket->priv->fd = g_value_get_int (value);
144         break;
145
146       case PROP_BLOCKING:
147         g_socket_set_blocking (socket, g_value_get_boolean (value));
148         break;
149
150       case PROP_BACKLOG:
151         socket->priv->backlog = g_value_get_int (value);
152         break;
153
154       case PROP_REUSE_ADDRESS:
155         g_socket_set_reuse_address (socket, g_value_get_boolean (value));
156         break;
157
158       default:
159         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
160     }
161 }
162
163 static void
164 g_socket_finalize (GObject *object)
165 {
166   GSocket *socket = G_SOCKET (object);
167
168   if (socket->priv->local_address)
169     g_object_unref (socket->priv->local_address);
170
171   if (socket->priv->remote_address)
172     g_object_unref (socket->priv->remote_address);
173
174   if (G_OBJECT_CLASS (g_socket_parent_class)->finalize)
175     (*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object);
176 }
177
178 static void
179 g_socket_dispose (GObject *object)
180 {
181   GSocket *socket = G_SOCKET (object);
182
183   g_socket_close (socket);
184
185   if (G_OBJECT_CLASS (g_socket_parent_class)->dispose)
186     (*G_OBJECT_CLASS (g_socket_parent_class)->dispose) (object);
187 }
188
189 static void
190 g_socket_class_init (GSocketClass *klass)
191 {
192   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
193
194   // TODO: WSAStartup
195
196   g_type_class_add_private (klass, sizeof (GSocketPrivate));
197
198   gobject_class->finalize = g_socket_finalize;
199   gobject_class->dispose = g_socket_dispose;
200   gobject_class->constructed = g_socket_constructed;
201   gobject_class->set_property = g_socket_set_property;
202   gobject_class->get_property = g_socket_get_property;
203
204   g_object_class_install_property (gobject_class, PROP_DOMAIN,
205                                    g_param_spec_int ("domain",
206                                                      "file descriptor",
207                                                      "the socket's file descriptor",
208                                                      G_MININT,
209                                                      G_MAXINT,
210                                                      -1,
211                                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
212
213   g_object_class_install_property (gobject_class, PROP_TYPE,
214                                    g_param_spec_int ("fd",
215                                                      "file descriptor",
216                                                      "the socket's file descriptor",
217                                                      G_MININT,
218                                                      G_MAXINT,
219                                                      -1,
220                                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
221
222   g_object_class_install_property (gobject_class, PROP_PROTOCOL,
223                                    g_param_spec_int ("fd",
224                                                      "file descriptor",
225                                                      "the socket's file descriptor",
226                                                      G_MININT,
227                                                      G_MAXINT,
228                                                      -1,
229                                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
230
231   g_object_class_install_property (gobject_class, PROP_FD,
232                                    g_param_spec_int ("fd",
233                                                      "file descriptor",
234                                                      "the socket's file descriptor",
235                                                      G_MININT,
236                                                      G_MAXINT,
237                                                      -1,
238                                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
239
240   g_object_class_install_property (gobject_class, PROP_BLOCKING,
241                                    g_param_spec_boolean ("blocking",
242                                                          "blocking",
243                                                          "whether or not this socket is blocking",
244                                                          TRUE,
245                                                          G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
246
247   g_object_class_install_property (gobject_class, PROP_BACKLOG,
248                                    g_param_spec_int ("backlog",
249                                                      "listen backlog",
250                                                      "outstanding connections in the listen queue",
251                                                      0,
252                                                      SOMAXCONN,
253                                                      10,
254                                                      G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
255
256   g_object_class_install_property (gobject_class, PROP_REUSE_ADDRESS,
257                                    g_param_spec_boolean ("reuse-address",
258                                                          "reuse address",
259                                                          "allow reuse of local addresses when binding",
260                                                          FALSE,
261                                                          G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
262
263   g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
264                                    g_param_spec_object ("local-address",
265                                                         "local address",
266                                                         "the local address the socket is bound to",
267                                                         G_TYPE_SOCKET_ADDRESS,
268                                                         G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
269
270   g_object_class_install_property (gobject_class, PROP_REMOTE_ADDRESS,
271                                    g_param_spec_object ("remote-address",
272                                                         "remote address",
273                                                         "the remote address the socket is connected to",
274                                                         G_TYPE_SOCKET_ADDRESS,
275                                                         G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
276 }
277
278 static void
279 g_socket_init (GSocket *socket)
280 {
281   socket->priv = G_TYPE_INSTANCE_GET_PRIVATE (socket, G_TYPE_SOCKET, GSocketPrivate);
282
283   socket->priv->fd = -1;
284   socket->priv->blocking = TRUE;
285   socket->priv->backlog = 10;
286   socket->priv->reuse_address = FALSE;
287   socket->priv->error = NULL;
288   socket->priv->remote_address = NULL;
289   socket->priv->local_address = NULL;
290 }
291
292 GSocket *
293 g_socket_new (GSocketDomain domain, GSocketType type, const gchar *protocol)
294 {
295   GError *error = NULL;
296   static GStaticMutex getprotobyname_mutex = G_STATIC_MUTEX_INIT;
297   gint fd, native_domain, native_type, native_protocol;
298
299   switch (domain)
300     {
301       case G_SOCKET_DOMAIN_INET:
302         native_domain = PF_INET;
303         break;
304
305       case G_SOCKET_DOMAIN_INET6:
306         native_domain = PF_INET6;
307         break;
308
309       case G_SOCKET_DOMAIN_UNIX:
310         native_domain = PF_UNIX;
311         break;
312
313       default:
314         g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported socket domain");
315         return NULL;
316     }
317
318   switch (type)
319     {
320       case G_SOCKET_TYPE_STREAM:
321         native_type = SOCK_STREAM;
322         break;
323
324       case G_SOCKET_TYPE_DATAGRAM:
325         native_type = SOCK_DGRAM;
326         break;
327
328       case G_SOCKET_TYPE_SEQPACKET:
329         native_type = SOCK_SEQPACKET;
330         break;
331
332       default:
333         g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported socket type");
334         return NULL;
335     }
336
337   if (protocol == NULL)
338     native_protocol = 0;
339   else
340     {
341       struct protoent *ent;
342       g_static_mutex_lock (&getprotobyname_mutex);
343       if (!(ent = getprotobyname (protocol)))
344         {
345           g_static_mutex_unlock (&getprotobyname_mutex);
346           g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported socket protocol");
347           return NULL;
348         }
349       native_protocol = ent->p_proto;
350       g_static_mutex_unlock (&getprotobyname_mutex);
351     }
352
353   fd = socket(native_domain, native_type, native_protocol);
354
355   if (fd < 0)
356     {
357       g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (errno), "unable to create socket: %s", g_strerror (errno));
358       return NULL;
359     }
360
361   g_print ("finishing socket_new\n");
362
363   return G_SOCKET (g_object_new (G_TYPE_SOCKET, "blocking", TRUE, "fd", fd, NULL));
364 }
365
366 GSocket *
367 g_socket_new_from_fd (gint fd)
368 {
369   glong arg;
370   gboolean blocking;
371
372   if ((arg = fcntl (fd, F_GETFL, NULL)) < 0)
373     g_warning ("Error getting socket status flags: %s", g_strerror (errno));
374
375   blocking = ((arg & O_NONBLOCK) == 0);
376
377   return G_SOCKET (g_object_new (G_TYPE_SOCKET, "fd", fd, "blocking", blocking, NULL));
378 }
379
380 void
381 g_socket_set_blocking (GSocket  *socket,
382                        gboolean  blocking)
383 {
384   glong arg;
385
386   g_return_if_fail (G_IS_SOCKET (socket));
387
388   if ((arg = fcntl (socket->priv->fd, F_GETFL, NULL)) < 0)
389     g_warning ("Error getting socket status flags: %s", g_strerror (errno));
390
391   arg = blocking ? arg & ~O_NONBLOCK : arg | O_NONBLOCK;
392
393   if (fcntl (socket->priv->fd, F_SETFL, arg) < 0)
394     g_warning ("Error setting socket status flags: %s", g_strerror (errno));
395
396   socket->priv->blocking = blocking;
397 }
398
399 gboolean
400 g_socket_get_blocking (GSocket *socket)
401 {
402   g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
403
404   return socket->priv->blocking;
405 }
406
407 void
408 g_socket_set_reuse_address (GSocket  *socket,
409                             gboolean  reuse)
410 {
411   gint value = (gint) reuse;
412
413   g_return_if_fail (G_IS_SOCKET (socket));
414
415   if (setsockopt (socket->priv->fd, SOL_SOCKET, SO_REUSEADDR, (gpointer) &value, sizeof (value)) < 0)
416     g_warning ("error setting reuse address: %s", g_strerror (errno));
417
418   socket->priv->reuse_address = reuse;
419 }
420
421 gboolean
422 g_socket_get_reuse_address (GSocket *socket)
423 {
424   g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
425
426   return socket->priv->reuse_address;
427 }
428
429 GSocketAddress *
430 g_socket_get_local_address (GSocket  *socket,
431                             GError  **error)
432 {
433   gchar buffer[256];
434   gsize len = 256;
435
436   g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
437
438   if (socket->priv->local_address)
439     return socket->priv->local_address;
440
441   if (getsockname (socket->priv->fd, (struct sockaddr *) buffer, &len) < 0)
442     {
443       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not get local address: %s", g_strerror (errno));
444       return NULL;
445     }
446
447   return (socket->priv->local_address = g_object_ref_sink (g_socket_address_from_native (buffer, len)));
448 }
449
450 GSocketAddress *
451 g_socket_get_remote_address (GSocket  *socket,
452                              GError  **error)
453 {
454   gchar buffer[256];
455   gsize len = 256;
456
457   g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
458
459   if (socket->priv->remote_address)
460     return socket->priv->remote_address;
461
462   if (getpeername (socket->priv->fd, (struct sockaddr *) buffer, &len) < 0)
463     {
464       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not get remote address: %s", g_strerror (errno));
465       return NULL;
466     }
467
468   return (socket->priv->remote_address = g_object_ref_sink (g_socket_address_from_native (buffer, len)));
469 }
470
471 gboolean
472 g_socket_has_error (GSocket  *socket,
473                     GError  **error)
474 {
475   g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
476
477   if (!socket->priv->error)
478     return FALSE;
479
480   return TRUE;
481 }
482
483 gboolean
484 g_socket_listen (GSocket  *socket,
485                  GError  **error)
486 {
487   g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
488
489   if (g_socket_has_error (socket, error))
490     return FALSE;
491
492   if (listen (socket->priv->fd, socket->priv->backlog) < 0)
493     {
494       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not listen: %s", g_strerror (errno));
495       return FALSE;
496     }
497
498   return TRUE;
499 }
500
501 gboolean
502 g_socket_bind (GSocket         *socket,
503                GSocketAddress  *address,
504                GError         **error)
505 {
506   g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE);
507
508   if (g_socket_has_error (socket, error))
509     return FALSE;
510
511   {
512     gchar addr[256];
513
514     if (!g_socket_address_to_native (address, addr))
515       return FALSE;
516
517     if (bind (socket->priv->fd, (struct sockaddr *) addr, g_socket_address_native_size (address)) < 0)
518       {
519         g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error binding to address: %s", g_strerror (errno));
520         return FALSE;
521       }
522
523     g_object_ref_sink (address);
524
525     socket->priv->local_address = address;
526
527     return TRUE;
528   }
529 }
530
531 GSocket *
532 g_socket_accept (GSocket       *socket,
533                  GError       **error)
534 {
535   gint ret;
536
537   g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
538
539   if (g_socket_has_error (socket, error))
540     return NULL;
541
542   if ((ret = accept (socket->priv->fd, NULL, 0)) < 0)
543     {
544       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error accepting connection: %s", g_strerror (errno));
545       return NULL;
546     }
547
548   return g_socket_new_from_fd (ret);
549 }
550
551 gboolean
552 g_socket_connect (GSocket         *socket,
553                   GSocketAddress  *address,
554                   GError         **error)
555 {
556   gchar buffer[256];
557
558   g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE);
559
560   if (g_socket_has_error (socket, error))
561     return FALSE;
562
563   g_socket_address_to_native (address, buffer);
564
565   if (connect (socket->priv->fd, (struct sockaddr *) buffer, g_socket_address_native_size (address)) < 0)
566     {
567       if (errno == EINPROGRESS)
568         g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING, "connection in progress");
569       else
570         g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error connecting: %s", g_strerror (errno));
571       return FALSE;
572     }
573
574   socket->priv->remote_address = g_object_ref_sink (address);
575
576   return TRUE;
577 }
578
579 gssize
580 g_socket_receive (GSocket       *socket,
581                   gchar         *buffer,
582                   gsize          size,
583                   GError       **error)
584 {
585   gssize ret;
586
587   g_return_val_if_fail (G_IS_SOCKET (socket) && buffer != NULL, FALSE);
588
589   if ((ret = recv (socket->priv->fd, buffer, size, 0)) < 0)
590     {
591       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error receiving data: %s", g_strerror (errno));
592       return -1;
593     }
594
595   return ret;
596 }
597
598 gssize
599 g_socket_send (GSocket       *socket,
600                gchar         *buffer,
601                gsize          size,
602                GError       **error)
603 {
604   gssize ret;
605
606   g_return_val_if_fail (G_IS_SOCKET (socket) && buffer != NULL, FALSE);
607
608   if ((ret = send (socket->priv->fd, buffer, size, 0)) < 0)
609     {
610       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "error sending data: %s", g_strerror (errno));
611       return -1;
612     }
613
614   return ret;
615 }
616
617 void
618 g_socket_close (GSocket *socket)
619 {
620   g_return_if_fail (G_IS_SOCKET (socket));
621
622 #ifdef G_OS_WIN32
623   closesocket (socket->priv->fd);
624 #else
625   close (socket->priv->fd);
626 #endif
627 }
628
629 GSource *
630 g_socket_create_source (GSocket      *socket,
631                         GIOCondition  condition,
632                         GCancellable *cancellable)
633 {
634   g_return_val_if_fail (G_IS_SOCKET (socket) && (cancellable == NULL || G_IS_CANCELLABLE (cancellable)), NULL);
635
636   return _g_fd_source_new (socket->priv->fd, G_IO_IN | G_IO_HUP | G_IO_ERR, cancellable);
637 }