2 * This file is part of the Nice GLib ICE library.
4 * (C) 2007 Nokia Corporation. All rights reserved.
5 * Contact: Rémi Denis-Courmont
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is the Nice GLib ICE library.
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
23 * Rémi Denis-Courmont, Nokia
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
40 #include <sys/types.h>
41 #include "stun/stunagent.h"
42 #include "stun/usages/turn.h"
53 #define MSG_DONTWAIT 0
54 #define MSG_NOSIGNAL 0
57 #define close closesocket
59 #include <sys/types.h>
60 #include <sys/socket.h>
61 #include <arpa/inet.h>
66 #undef NDEBUG /* ensure assertions are built-in */
70 static int listen_dgram (void)
72 struct addrinfo hints, *res;
75 memset (&hints, 0, sizeof (hints));
76 hints.ai_socktype = SOCK_DGRAM;
78 if (getaddrinfo (NULL, "0", &hints, &res))
81 for (const struct addrinfo *ptr = res; ptr != NULL; ptr = ptr->ai_next)
83 int fd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
87 if (bind (fd, ptr->ai_addr, ptr->ai_addrlen))
103 printaddr (const char *str, const struct sockaddr *addr, socklen_t addrlen)
105 char hostbuf[NI_MAXHOST], servbuf[NI_MAXSERV];
107 int val = getnameinfo (addr, addrlen, hostbuf, sizeof (hostbuf),
108 servbuf, sizeof (servbuf),
109 NI_NUMERICHOST | NI_NUMERICSERV);
111 printf ("%s: %s\n", str, gai_strerror (val));
113 printf ("%s: %s port %s\n", str, hostbuf, servbuf);
117 /** Various responses test */
118 static void test_turn (char *username, char *password, char *hostname, int port)
120 struct sockaddr_storage addr;
121 socklen_t addrlen = sizeof (addr);
122 struct sockaddr_storage alternate_addr;
123 socklen_t alternate_addrlen = sizeof (alternate_addr);
124 struct sockaddr_storage relay_addr;
125 socklen_t relay_addrlen = sizeof (relay_addr);
129 uint8_t buf[STUN_MAX_MESSAGE_SIZE];
130 uint8_t req[STUN_MAX_MESSAGE_SIZE];
131 uint8_t refresh[STUN_MAX_MESSAGE_SIZE];
136 StunMessage refresh_msg;
137 uint32_t bandwidth, lifetime;
138 struct addrinfo hints, *res;
141 memset (&hints, 0, sizeof (hints));
142 hints.ai_family = AF_UNSPEC;
143 hints.ai_socktype = SOCK_DGRAM;
146 ret = getaddrinfo (hostname, port, &hints, &res);
149 stun_agent_init (&agent, STUN_ALL_KNOWN_ATTRIBUTES,
150 STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS);
152 /* Allocate a client socket and connect to server */
153 fd = socket (AF_INET, SOCK_DGRAM, 0);
156 val = connect (fd,res->ai_addr, res->ai_addrlen);
158 assert (val == 0 || (WSAGetLastError () == WSAEINPROGRESS));
160 assert (val == 0 || (errno == EINPROGRESS));
166 /* Send old-style response */
167 req_len = stun_usage_turn_create (&agent, &req_msg, req, sizeof(req),
169 STUN_USAGE_TURN_REQUEST_PORT_NORMAL,
171 username, strlen (username), password, strlen(password),
172 STUN_USAGE_TURN_COMPATIBILITY_DRAFT9);
173 assert (req_len > 0);
175 val = send (fd, req, req_len, MSG_NOSIGNAL);
178 val = recv (fd, buf, 1000, 0);
181 assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL)
182 == STUN_VALIDATION_SUCCESS);
184 val = stun_usage_turn_process (&msg,
185 (struct sockaddr *)&relay_addr, &relay_addrlen,
186 (struct sockaddr *)&addr, &addrlen,
187 (struct sockaddr *)&alternate_addr, &alternate_addrlen,
188 &bandwidth, &lifetime,
189 STUN_USAGE_TURN_COMPATIBILITY_DRAFT9);
190 assert (val == STUN_USAGE_TURN_RETURN_ERROR);
192 req_len = stun_usage_turn_create (&agent, &req_msg, req, sizeof(req),
194 STUN_USAGE_TURN_REQUEST_PORT_NORMAL,
196 username, strlen (username), password, strlen(password),
197 STUN_USAGE_TURN_COMPATIBILITY_DRAFT9);
198 assert (req_len > 0);
200 val = send (fd, req, req_len, MSG_NOSIGNAL);
203 val = recv (fd, buf, 1000, 0);
206 assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL)
207 == STUN_VALIDATION_SUCCESS);
209 val = stun_usage_turn_process (&msg,
210 (struct sockaddr *)&relay_addr, &relay_addrlen,
211 (struct sockaddr *)&addr, &addrlen,
212 (struct sockaddr *)&alternate_addr, &alternate_addrlen,
213 &bandwidth, &lifetime,
214 STUN_USAGE_TURN_COMPATIBILITY_DRAFT9);
215 assert (val == STUN_USAGE_TURN_RETURN_MAPPED_SUCCESS);
217 printaddr ("Relay address found : ", (struct sockaddr *)&relay_addr, relay_addrlen);
218 printaddr ("Mapped address found : ",(struct sockaddr *) &addr, addrlen);
221 req_len = stun_usage_turn_create_refresh (&agent, &refresh_msg, refresh,
222 sizeof(refresh), &req_msg, 0, username, strlen (username),
223 password, strlen(password),STUN_USAGE_TURN_COMPATIBILITY_DRAFT9);
224 assert (req_len > 0);
226 val = send (fd, refresh, req_len, MSG_NOSIGNAL);
229 val = recv (fd, buf, 1000, 0);
232 assert (stun_agent_validate (&agent, &msg, buf, val, NULL, NULL)
233 == STUN_VALIDATION_SUCCESS);
239 static void turnserver (void)
241 test_turn ("toto", "password", "127.0.0.1", "3478");
244 static void numb (void)
246 test_turn ("youness.alaoui@collabora.co.uk", "badger", "numb.viagenie.ca", "3478");
249 static void test (void (*func) (void), const char *name)
253 printf ("%s test... ", name);
261 test (turnserver, "Testing TURN");
262 test (numb, "Testing numb");