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.)
59 static void socket_close (NiceSocket
*sock
);
60 static gint
socket_recv (NiceSocket
*sock
, NiceAddress
*from
,
61 guint len
, gchar
*buf
);
62 static gboolean
socket_send (NiceSocket
*sock
, const NiceAddress
*to
,
63 guint len
, const gchar
*buf
);
64 static gboolean
socket_is_reliable (NiceSocket
*sock
);
67 nice_udp_bsd_socket_new (NiceAddress
*addr
)
70 struct sockaddr_storage name
;
71 socklen_t name_len
= sizeof (name
);
72 NiceSocket
*sock
= g_slice_new0 (NiceSocket
);
74 unsigned long set_nonblock
=1;
78 nice_address_copy_to_sockaddr(addr
, (struct sockaddr
*)&name
);
80 memset (&name
, 0, sizeof (name
));
81 name
.ss_family
= AF_UNSPEC
;
84 if (name
.ss_family
== AF_UNSPEC
|| name
.ss_family
== AF_INET
) {
85 sockfd
= socket (PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
86 name
.ss_family
= AF_INET
;
88 name
.ss_len
= sizeof (struct sockaddr_in
);
90 } else if (name
.ss_family
== AF_INET6
) {
91 sockfd
= socket (PF_INET6
, SOCK_DGRAM
, IPPROTO_UDP
);
92 name
.ss_family
= AF_INET6
;
94 name
.ss_len
= sizeof (struct sockaddr_in6
);
99 g_slice_free (NiceSocket
, sock
);
104 fcntl (sockfd
, F_SETFD
, fcntl (sockfd
, F_GETFD
) | FD_CLOEXEC
);
107 fcntl (sockfd
, F_SETFL
, fcntl (sockfd
, F_GETFL
) | O_NONBLOCK
);
108 #elif defined G_OS_WIN32
109 ioctlsocket(sockfd
, FIONBIO
, &set_nonblock
);
112 if(bind (sockfd
, (struct sockaddr
*) &name
,
113 name
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
114 sizeof(struct sockaddr_in6
)) < 0) {
115 g_slice_free (NiceSocket
, sock
);
124 name_len
= name
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
125 sizeof(struct sockaddr_in6
);
126 if (getsockname (sockfd
, (struct sockaddr
*) &name
, &name_len
) < 0) {
127 g_slice_free (NiceSocket
, sock
);
136 nice_address_set_from_sockaddr (&sock
->addr
, (struct sockaddr
*)&name
);
137 sock
->fileno
= sockfd
;
139 sock
->send
= socket_send
;
140 sock
->recv
= socket_recv
;
141 sock
->is_reliable
= socket_is_reliable
;
142 sock
->close
= socket_close
;
148 socket_close (NiceSocket
*sock
)
151 closesocket(sock
->fileno
);
153 close (sock
->fileno
);
158 socket_recv (NiceSocket
*sock
, NiceAddress
*from
, guint len
, gchar
*buf
)
161 struct sockaddr_storage sa
;
162 socklen_t from_len
= sizeof (sa
);
164 recvd
= recvfrom (sock
->fileno
, buf
, len
, 0, (struct sockaddr
*) &sa
,
169 if (WSAGetLastError () == WSAEWOULDBLOCK
||
170 WSAGetLastError () == WSAECONNRESET
)
172 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
)
178 nice_address_set_from_sockaddr (from
, (struct sockaddr
*)&sa
);
184 socket_send (NiceSocket
*sock
, const NiceAddress
*to
,
185 guint len
, const gchar
*buf
)
187 struct sockaddr_storage sa
;
190 nice_address_copy_to_sockaddr (to
, (struct sockaddr
*)&sa
);
192 sent
= sendto (sock
->fileno
, buf
, len
, 0, (struct sockaddr
*) &sa
,
193 sa
.ss_family
== AF_INET
? sizeof (struct sockaddr_in
) :
194 sizeof(struct sockaddr_in6
));
196 return sent
== (ssize_t
)len
;
200 socket_is_reliable (NiceSocket
*sock
)