2 * This file is part of the Nice GLib ICE library.
4 * (C) 2006, 2007 Collabora Ltd.
5 * Contact: Dafydd Harries
6 * (C) 2006, 2007 Nokia Corporation. All rights reserved.
7 * Contact: Kai Vehmanen
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
19 * The Original Code is the Nice GLib ICE library.
21 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22 * Corporation. All Rights Reserved.
25 * Dafydd Harries, Collabora Ltd.
26 * RĂ©mi Denis-Courmont, Nokia
29 * Alternatively, the contents of this file may be used under the terms of the
30 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
31 * case the provisions of LGPL are applicable instead of those above. If you
32 * wish to allow use of your version of this file only under the terms of the
33 * LGPL and not to allow others to use your version of this file under the
34 * MPL, indicate your decision by deleting the provisions above and replace
35 * them with the notice and other provisions required by the LGPL. If you do
36 * not delete the provisions above, a recipient may use your version of this
37 * file under either the MPL or the LGPL.
41 * Implementation of UDP socket interface using Berkeley sockets. (See
42 * http://en.wikipedia.org/wiki/Berkeley_sockets.)
56 typedef unsigned long ssize_t
;
62 static void socket_close (NiceSocket
*sock
);
63 static gint
socket_recv (NiceSocket
*sock
, NiceAddress
*from
,
64 guint len
, gchar
*buf
);
65 static gboolean
socket_send (NiceSocket
*sock
, const NiceAddress
*to
,
66 guint len
, const gchar
*buf
);
67 static gboolean
socket_is_reliable (NiceSocket
*sock
);
70 nice_udp_bsd_socket_new (NiceAddress
*addr
)
73 struct sockaddr_storage name
;
74 socklen_t name_len
= sizeof (name
);
75 NiceSocket
*sock
= g_slice_new0 (NiceSocket
);
82 nice_address_copy_to_sockaddr(addr
, (struct sockaddr
*)&name
);
84 memset (&name
, 0, sizeof (name
));
85 name
.ss_family
= AF_UNSPEC
;
88 if (name
.ss_family
== AF_UNSPEC
|| name
.ss_family
== AF_INET
) {
89 sockfd
= socket (PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
90 name
.ss_family
= AF_INET
;
92 name
.ss_len
= sizeof (struct sockaddr_in
);
97 g_slice_free (NiceSocket
, sock
);
102 fcntl (sockfd
, F_SETFD
, fcntl (sockfd
, F_GETFD
) | FD_CLOEXEC
);
105 fcntl (sockfd
, F_SETFL
, fcntl (sockfd
, F_GETFL
) | O_NONBLOCK
);
108 if(bind (sockfd
, (struct sockaddr
*) &name
,
109 name
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
110 sizeof(struct sockaddr_in6
)) < 0) {
111 g_slice_free (NiceSocket
, sock
);
120 name_len
= name
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
121 sizeof(struct sockaddr_in6
);
122 if (getsockname (sockfd
, (struct sockaddr
*) &name
, &name_len
) < 0) {
123 g_slice_free (NiceSocket
, sock
);
132 nice_address_set_from_sockaddr (&sock
->addr
, (struct sockaddr
*)&name
);
133 sock
->fileno
= sockfd
;
135 sock
->send
= socket_send
;
136 sock
->recv
= socket_recv
;
137 sock
->is_reliable
= socket_is_reliable
;
138 sock
->close
= socket_close
;
144 socket_close (NiceSocket
*sock
)
147 closesocket(sock
->fileno
);
149 close (sock
->fileno
);
154 socket_recv (NiceSocket
*sock
, NiceAddress
*from
, guint len
, gchar
*buf
)
157 struct sockaddr_storage sa
;
158 socklen_t from_len
= sizeof (sa
);
160 recvd
= recvfrom (sock
->fileno
, buf
, len
, 0, (struct sockaddr
*) &sa
,
164 nice_address_set_from_sockaddr (from
, (struct sockaddr
*)&sa
);
170 socket_send (NiceSocket
*sock
, const NiceAddress
*to
,
171 guint len
, const gchar
*buf
)
173 struct sockaddr_storage sa
;
176 nice_address_copy_to_sockaddr (to
, (struct sockaddr
*)&sa
);
178 sent
= sendto (sock
->fileno
, buf
, len
, 0, (struct sockaddr
*) &sa
,
179 sa
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
180 sizeof(struct sockaddr_in6
));
182 return sent
== (ssize_t
)len
;
186 socket_is_reliable (NiceSocket
*sock
)