2 * This file is part of the Nice GLib ICE library.
4 * (C) 2006-2009 Collabora Ltd.
5 * Contact: Youness Alaoui
6 * (C) 2006-2009 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 * Youness Alaoui, Collabora Ltd.
28 * Alternatively, the contents of this file may be used under the terms of the
29 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
30 * case the provisions of LGPL are applicable instead of those above. If you
31 * wish to allow use of your version of this file only under the terms of the
32 * LGPL and not to allow others to use your version of this file under the
33 * MPL, indicate your decision by deleting the provisions above and replace
34 * them with the notice and other provisions required by the LGPL. If you do
35 * not delete the provisions above, a recipient may use your version of this
36 * file under either the MPL or the LGPL.
40 * Implementation of UDP socket interface using Berkeley sockets. (See
41 * http://en.wikipedia.org/wiki/Berkeley_sockets.)
55 typedef unsigned long ssize_t
;
61 static void socket_close (NiceSocket
*sock
);
62 static gint
socket_recv (NiceSocket
*sock
, NiceAddress
*from
,
63 guint len
, gchar
*buf
);
64 static gboolean
socket_send (NiceSocket
*sock
, const NiceAddress
*to
,
65 guint len
, const gchar
*buf
);
66 static gboolean
socket_is_reliable (NiceSocket
*sock
);
69 nice_udp_bsd_socket_new (NiceAddress
*addr
)
72 struct sockaddr_storage name
;
73 socklen_t name_len
= sizeof (name
);
74 NiceSocket
*sock
= g_slice_new0 (NiceSocket
);
77 nice_address_copy_to_sockaddr(addr
, (struct sockaddr
*)&name
);
79 memset (&name
, 0, sizeof (name
));
80 name
.ss_family
= AF_UNSPEC
;
83 if (name
.ss_family
== AF_UNSPEC
|| name
.ss_family
== AF_INET
) {
84 sockfd
= socket (PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
85 name
.ss_family
= AF_INET
;
87 name
.ss_len
= sizeof (struct sockaddr_in
);
89 } else if (name
.ss_family
== AF_INET6
) {
90 sockfd
= socket (PF_INET6
, SOCK_DGRAM
, IPPROTO_UDP
);
91 name
.ss_family
= AF_INET6
;
93 name
.ss_len
= sizeof (struct sockaddr_in6
);
98 g_slice_free (NiceSocket
, sock
);
103 fcntl (sockfd
, F_SETFD
, fcntl (sockfd
, F_GETFD
) | FD_CLOEXEC
);
106 fcntl (sockfd
, F_SETFL
, fcntl (sockfd
, F_GETFL
) | O_NONBLOCK
);
109 if(bind (sockfd
, (struct sockaddr
*) &name
,
110 name
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
111 sizeof(struct sockaddr_in6
)) < 0) {
112 g_slice_free (NiceSocket
, sock
);
121 name_len
= name
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
122 sizeof(struct sockaddr_in6
);
123 if (getsockname (sockfd
, (struct sockaddr
*) &name
, &name_len
) < 0) {
124 g_slice_free (NiceSocket
, sock
);
133 nice_address_set_from_sockaddr (&sock
->addr
, (struct sockaddr
*)&name
);
134 sock
->fileno
= sockfd
;
136 sock
->send
= socket_send
;
137 sock
->recv
= socket_recv
;
138 sock
->is_reliable
= socket_is_reliable
;
139 sock
->close
= socket_close
;
145 socket_close (NiceSocket
*sock
)
148 closesocket(sock
->fileno
);
150 close (sock
->fileno
);
155 socket_recv (NiceSocket
*sock
, NiceAddress
*from
, guint len
, gchar
*buf
)
158 struct sockaddr_storage sa
;
159 socklen_t from_len
= sizeof (sa
);
161 recvd
= recvfrom (sock
->fileno
, buf
, len
, 0, (struct sockaddr
*) &sa
,
166 if (WSAGetLastError () == WSAEWOULDBLOCK
)
168 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
)
174 nice_address_set_from_sockaddr (from
, (struct sockaddr
*)&sa
);
180 socket_send (NiceSocket
*sock
, const NiceAddress
*to
,
181 guint len
, const gchar
*buf
)
183 struct sockaddr_storage sa
;
186 nice_address_copy_to_sockaddr (to
, (struct sockaddr
*)&sa
);
188 sent
= sendto (sock
->fileno
, buf
, len
, 0, (struct sockaddr
*) &sa
,
189 sa
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
190 sizeof(struct sockaddr_in6
));
192 return sent
== (ssize_t
)len
;
196 socket_is_reliable (NiceSocket
*sock
)