Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / socket / socket.c
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2008-2009 Collabora Ltd.
5  *  Contact: Youness Alaoui
6  * (C) 2008-2009 Nokia Corporation. All rights reserved.
7  *
8  * The contents of this file are subject to the Mozilla Public License Version
9  * 1.1 (the "License"); you may not use this file except in compliance with
10  * the License. You may obtain a copy of the License at
11  * http://www.mozilla.org/MPL/
12  *
13  * Software distributed under the License is distributed on an "AS IS" basis,
14  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15  * for the specific language governing rights and limitations under the
16  * License.
17  *
18  * The Original Code is the Nice GLib ICE library.
19  *
20  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21  * Corporation. All Rights Reserved.
22  *
23  * Contributors:
24  *   Youness Alaoui, Collabora Ltd.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28  * case the provisions of LGPL are applicable instead of those above. If you
29  * wish to allow use of your version of this file only under the terms of the
30  * LGPL and not to allow others to use your version of this file under the
31  * MPL, indicate your decision by deleting the provisions above and replace
32  * them with the notice and other provisions required by the LGPL. If you do
33  * not delete the provisions above, a recipient may use your version of this
34  * file under either the MPL or the LGPL.
35  */
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39
40
41 #include <glib.h>
42
43 #include "socket.h"
44 #include "socket-priv.h"
45 #include "agent-priv.h"
46
47 #include <string.h>
48
49 #ifndef G_OS_WIN32
50 #include <unistd.h>
51 #endif
52
53 typedef struct _NiceSocketQueuedSend NiceSocketQueuedSend;
54
55 struct _NiceSocketQueuedSend {
56   guint8 *buf;  /* owned */
57   gsize length;
58   NiceAddress to;
59 };
60
61 /**
62  * nice_socket_recv_messages:
63  * @sock: a #NiceSocket
64  * @recv_messages: (array length=n_recv_messages) (out caller-allocates):
65  * array of #NiceInputMessages to return received messages in
66  * @n_recv_messages: number of elements in the @recv_messages array
67  *
68  * Receive up to @n_recv_messages message on the socket, in a non-reliable,
69  * non-blocking fashion. The total size of the buffers in each #NiceInputMessage
70  * must be big enough to contain an entire message (65536 bytes), or excess
71  * bytes will be silently dropped.
72  *
73  * On success, the number of messages received into @recv_messages is returned,
74  * which may be less than @n_recv_messages if the call would have blocked
75  * part-way through. If the socket would have blocked to begin with, or if
76  * @n_recv_messages is zero, zero is returned. On failure, a negative value is
77  * returned, but no further error information is available. Calling this
78  * function on a socket which has closed is an error, and a negative value is
79  * returned.
80  *
81  * If a positive N is returned, the first N messages in @recv_messages are
82  * valid. Each valid message is guaranteed to have a non-zero
83  * #NiceInputMessage::length, and its buffers are guaranteed to be filled
84  * sequentially up to that number of bytes  If #NiceInputMessage::from was
85  * non-%NULL for a valid message, it may be set to the address of the sender of
86  * that received message.
87  *
88  * If the return value is zero or negative, the from return address and length
89  * in every #NiceInputMessage in @recv_messages are guaranteed to be unmodified.
90  * The buffers may have been modified.
91  *
92  * The base addresses and sizes of the buffers in a #NiceInputMessage are never
93  * modified. Neither is the base address of #NiceInputMessage::from, nor the
94  * base address and length of the #NiceInputMessage::buffers array.
95  *
96  * Returns: number of valid messages returned in @recv_messages, or a negative
97  * value on error
98  *
99  * Since: 0.1.5
100  */
101 gint
102 nice_socket_recv_messages (NiceSocket *sock,
103     NiceInputMessage *recv_messages, guint n_recv_messages)
104 {
105   g_return_val_if_fail (sock != NULL, -1);
106   g_return_val_if_fail (n_recv_messages == 0 || recv_messages != NULL, -1);
107
108   return sock->recv_messages (sock, recv_messages, n_recv_messages);
109 }
110
111 /**
112  * nice_socket_send_messages:
113  * @sock: a #NiceSocket
114  * @messages: (array length=n_messages) (in caller-allocates):
115  * array of #NiceOutputMessages containing the messages to send
116  * @n_messages: number of elements in the @messages array
117  *
118  * Send up to @n_messages on the socket, in a non-reliable, non-blocking
119  * fashion. The total size of the buffers in each #NiceOutputMessage
120  * must be at most the maximum UDP payload size (65535 bytes), or excess
121  * bytes will be silently dropped.
122  *
123  * On success, the number of messages transmitted from @messages is returned,
124  * which may be less than @n_messages if the call would have blocked
125  * part-way through. If the socket would have blocked to begin with, or if
126  * @n_messages is zero, zero is returned. On failure, a negative value is
127  * returned, but no further error information is available. Calling this
128  * function on a socket which has closed is an error, and a negative value is
129  * returned.
130  *
131  * If a positive N is returned, the first N messages in @messages have been
132  * sent in full, and the remaining messages have not been sent at all.
133  *
134  * If #NiceOutputMessage::to is specified for a message, that will be used as
135  * the destination address for the message. Otherwise, if %NULL, the default
136  * destination for @sock will be used.
137  *
138  * Every field of every #NiceOutputMessage is guaranteed to be unmodified when
139  * this function returns.
140  *
141  * Returns: number of messages successfully sent from @messages, or a negative
142  * value on error
143  *
144  * Since: 0.1.5
145  */
146 gint
147 nice_socket_send_messages (NiceSocket *sock, const NiceAddress *to,
148     const NiceOutputMessage *messages, guint n_messages)
149 {
150   g_return_val_if_fail (sock != NULL, -1);
151   g_return_val_if_fail (n_messages == 0 || messages != NULL, -1);
152
153   return sock->send_messages (sock, to, messages, n_messages);
154 }
155
156 /**
157  * nice_socket_send_messages_reliable:
158  * @sock: a #NiceSocket
159  * @messages: (array length=n_messages) (in caller-allocates):
160  * array of #NiceOutputMessages containing the messages to send
161  * @n_messages: number of elements in the @messages array
162  *
163  * Send @n_messages on the socket, in a reliable, non-blocking fashion.
164  * The total size of the buffers in each #NiceOutputMessage
165  * must be at most the maximum UDP payload size (65535 bytes), or excess
166  * bytes will be silently dropped.
167  *
168  * On success, the number of messages transmitted from @messages is returned,
169  * which will be equal to @n_messages. If the call would have blocked part-way
170  * though, the remaining bytes will be queued for sending later.
171  * On failure, a negative value is returned, but no further error information
172  * is available. Calling this function on a socket which has closed is an error,
173  * and a negative value is returned. Calling this function on a socket which
174  * is not TCP or does not have a TCP base socket, will result in an error.
175  *
176  * If #NiceOutputMessage::to is specified for a message, that will be used as
177  * the destination address for the message. Otherwise, if %NULL, the default
178  * destination for @sock will be used.
179  *
180  * Every field of every #NiceOutputMessage is guaranteed to be unmodified when
181  * this function returns.
182  *
183  * Returns: number of messages successfully sent from @messages, or a negative
184  * value on error
185  *
186  * Since: 0.1.5
187  */
188 gint
189 nice_socket_send_messages_reliable (NiceSocket *sock, const NiceAddress *to,
190     const NiceOutputMessage *messages, guint n_messages)
191 {
192   g_return_val_if_fail (sock != NULL, -1);
193   g_return_val_if_fail (n_messages == 0 || messages != NULL, -1);
194
195   return sock->send_messages_reliable (sock, to, messages, n_messages);
196 }
197
198 /* Convenience wrapper around nice_socket_recv_messages(). Returns the number of
199  * bytes received on success (which will be @len), zero if sending would block, or
200  * -1 on error. */
201 gssize
202 nice_socket_recv (NiceSocket *sock, NiceAddress *from, gsize len,
203     gchar *buf)
204 {
205   GInputVector local_buf = { buf, len };
206   NiceInputMessage local_message = { &local_buf, 1, from, 0};
207   gint ret;
208
209   ret = sock->recv_messages (sock, &local_message, 1);
210   if (ret == 1)
211     return local_message.length;
212   return ret;
213 }
214
215 /* Convenience wrapper around nice_socket_send_messages(). Returns the number of
216  * bytes sent on success (which will be @len), zero if sending would block, or
217  * -1 on error. */
218 gssize
219 nice_socket_send (NiceSocket *sock, const NiceAddress *to, gsize len,
220     const gchar *buf)
221 {
222   GOutputVector local_buf = { buf, len };
223   NiceOutputMessage local_message = { &local_buf, 1};
224   gint ret;
225
226   ret = sock->send_messages (sock, to, &local_message, 1);
227   if (ret == 1)
228     return len;
229   return ret;
230 }
231
232 gssize
233 nice_socket_send_reliable (NiceSocket *sock, const NiceAddress *to, gsize len,
234     const gchar *buf)
235 {
236   GOutputVector local_buf = { buf, len };
237   NiceOutputMessage local_message = { &local_buf, 1};
238   gint ret;
239
240   ret = sock->send_messages_reliable (sock, to, &local_message, 1);
241   if (ret == 1)
242     return len;
243   return ret;
244 }
245
246 gboolean
247 nice_socket_is_reliable (NiceSocket *sock)
248 {
249   return sock->is_reliable (sock);
250 }
251
252 gboolean
253 nice_socket_can_send (NiceSocket *sock, NiceAddress *addr)
254 {
255   if (sock->can_send)
256     return sock->can_send (sock, addr);
257   return TRUE;
258 }
259
260 void
261 nice_socket_set_writable_callback (NiceSocket *sock,
262     NiceSocketWritableCb callback, gpointer user_data)
263 {
264   if (sock->set_writable_callback)
265     sock->set_writable_callback (sock, callback, user_data);
266 }
267
268 gboolean
269 nice_socket_is_based_on (NiceSocket *sock, NiceSocket *other)
270 {
271   if (sock->is_based_on)
272     return sock->is_based_on (sock, other);
273   return (sock == other);
274 }
275
276 void
277 nice_socket_free (NiceSocket *sock)
278 {
279   if (sock) {
280     sock->close (sock);
281     g_slice_free (NiceSocket,sock);
282   }
283 }
284
285 static void
286 nice_socket_free_queued_send (NiceSocketQueuedSend *tbs)
287 {
288   g_free (tbs->buf);
289   g_slice_free (NiceSocketQueuedSend, tbs);
290 }
291
292 void
293 nice_socket_queue_send (GQueue *send_queue, const NiceAddress *to,
294     const NiceOutputMessage *messages, guint n_messages)
295 {
296   guint i;
297
298   if (n_messages == 0)
299     return;
300
301   /* Compact the message’s buffers before queueing. */
302   for (i = 0; i < n_messages; i++) {
303     NiceSocketQueuedSend *tbs;
304     const NiceOutputMessage *message = &messages[i];
305     gsize message_len_remaining = output_message_get_size (message);
306     guint j;
307     gsize offset = 0;
308
309     if (message_len_remaining == 0)
310       continue;
311
312     /* Compact the buffer. */
313     tbs = g_slice_new0 (NiceSocketQueuedSend);
314     tbs->buf = g_malloc (message_len_remaining);
315     tbs->length = message_len_remaining;
316
317     if (to)
318       tbs->to = *to;
319     else
320       memset (&tbs->to, 0, sizeof(NiceAddress));
321     g_queue_push_tail (send_queue, tbs);
322
323     for (j = 0;
324          (message->n_buffers >= 0 && j < (guint) message->n_buffers) ||
325          (message->n_buffers < 0 && message->buffers[j].buffer != NULL);
326          j++) {
327       const GOutputVector *buffer = &message->buffers[j];
328       gsize len;
329
330       len = MIN (buffer->size, message_len_remaining);
331       memcpy (tbs->buf + offset, buffer->buffer, len);
332       message_len_remaining -= len;
333       offset += len;
334     }
335
336     g_assert_cmpint (offset, ==, tbs->length);
337   }
338 }
339
340 void nice_socket_queue_send_with_callback (GQueue *send_queue,
341     const NiceOutputMessage *message, gsize message_offset, gsize message_len,
342     gboolean head, GSocket *gsock, GSource **io_source, GMainContext *context,
343     GSocketSourceFunc cb, gpointer user_data)
344 {
345   NiceSocketQueuedSend *tbs;
346   guint j;
347   gsize offset = 0;
348
349   if (message_offset >= message_len)
350     return;
351
352   tbs = g_slice_new0 (NiceSocketQueuedSend);
353   tbs->length = message_len - message_offset;
354   tbs->buf = g_malloc (tbs->length);
355
356   if (head)
357     g_queue_push_head (send_queue, tbs);
358   else
359     g_queue_push_tail (send_queue, tbs);
360
361   /* Move the data into the buffer. */
362   for (j = 0;
363        (message->n_buffers >= 0 && j < (guint) message->n_buffers) ||
364        (message->n_buffers < 0 && message->buffers[j].buffer != NULL);
365        j++) {
366     const GOutputVector *buffer = &message->buffers[j];
367     gsize len;
368
369     /* Skip this buffer if it’s within @message_offset. */
370     if (buffer->size <= message_offset) {
371       message_offset -= buffer->size;
372       continue;
373     }
374
375     len = MIN (tbs->length - offset, buffer->size - message_offset);
376     memcpy (tbs->buf + offset, (guint8 *) buffer->buffer + message_offset, len);
377     offset += len;
378     if (message_offset >= len)
379       message_offset -= len;
380     else
381       message_offset = 0;
382   }
383
384   if (io_source && gsock && context && cb && *io_source == NULL) {
385     *io_source = g_socket_create_source(gsock, G_IO_OUT, NULL);
386     g_source_set_callback (*io_source, (GSourceFunc) G_CALLBACK (cb), user_data, NULL);
387     g_source_attach (*io_source, context);
388   }
389 }
390
391 void nice_socket_flush_send_queue (NiceSocket *base_socket, GQueue *send_queue)
392 {
393   NiceSocketQueuedSend *tbs;
394
395   while ((tbs = g_queue_pop_head (send_queue))) {
396     NiceAddress *to = &tbs->to;
397
398     if (!nice_address_is_valid (to))
399       to = NULL;
400
401     /* We only queue reliable data */
402     nice_socket_send_reliable (base_socket, to,
403         tbs->length, (const gchar *) tbs->buf);
404     nice_socket_free_queued_send (tbs);
405   }
406 }
407
408 gboolean nice_socket_flush_send_queue_to_socket (GSocket *gsock,
409     GQueue *send_queue)
410 {
411   NiceSocketQueuedSend *tbs;
412   GError *gerr = NULL;
413
414
415   while ((tbs = g_queue_pop_head (send_queue)) != NULL) {
416     int ret;
417
418     GOutputVector local_bufs = { tbs->buf, tbs->length };
419     ret = g_socket_send_message (gsock, NULL, &local_bufs, 1, NULL, 0,
420         G_SOCKET_MSG_NONE, NULL, &gerr);
421
422     if (ret < 0) {
423       if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
424         GOutputVector local_buf = { tbs->buf, tbs->length };
425         NiceOutputMessage local_message = {&local_buf, 1};
426
427         nice_socket_queue_send_with_callback (send_queue, &local_message,
428             0, local_buf.size, TRUE, NULL, NULL, NULL, NULL, NULL);
429         nice_socket_free_queued_send (tbs);
430         g_error_free (gerr);
431         return FALSE;
432       }
433       g_clear_error (&gerr);
434     } else if (ret < (int) tbs->length) {
435       GOutputVector local_buf = { tbs->buf + ret, tbs->length - ret };
436       NiceOutputMessage local_message = {&local_buf, 1};
437
438       nice_socket_queue_send_with_callback (send_queue, &local_message,
439           0, local_buf.size, TRUE, NULL, NULL, NULL, NULL, NULL);
440       nice_socket_free_queued_send (tbs);
441       return FALSE;
442     }
443
444     nice_socket_free_queued_send (tbs);
445   }
446
447   return TRUE;
448 }
449
450 void
451 nice_socket_free_send_queue (GQueue *send_queue)
452 {
453   g_list_free_full (send_queue->head, (GDestroyNotify) nice_socket_free_queued_send);
454   g_queue_init (send_queue);
455 }