2
* Copyright (c) 2009-2010 Michael Kuhn
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35
#include <interfaces.h>
36
#include <stun/usages/bind.h>
39
#ifdef HAVE_GUPNP_IGD_1_0
40
#include <libgupnp-igd/gupnp-simple-igd.h>
45
makiInstance* instance;
55
struct sockaddr_storage addr;
62
#ifdef HAVE_GUPNP_IGD_1_0
63
GUPnPSimpleIgd* upnp_igd;
67
static gboolean maki_network_update_local (gpointer data)
69
makiNetwork* net = data;
71
g_mutex_lock(net->lock);
72
g_free(net->local.ip);
74
g_mutex_unlock(net->lock);
80
if ((ips = nice_interfaces_get_local_ips(FALSE)) != NULL)
84
g_mutex_lock(net->lock);
85
net->local.ip = g_strdup(ips->data);
86
g_mutex_unlock(net->lock);
88
for (l = ips; l != NULL; l = g_list_next(l))
101
static gboolean maki_network_update_remote (gpointer data)
103
makiNetwork* net = data;
105
g_mutex_lock(net->lock);
106
memset(&net->remote.addr, 0, sizeof(net->remote.addr));
107
net->remote.addrlen = 0;
108
g_mutex_unlock(net->lock);
116
struct addrinfo hints;
118
stun = maki_instance_config_get_string(net->instance, "network", "stun");
125
memset(&hints, 0, sizeof(hints));
126
hints.ai_family = AF_UNSPEC;
127
hints.ai_socktype = SOCK_DGRAM;
128
hints.ai_protocol = 0;
129
hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
131
if (getaddrinfo(stun, "3478", NULL, &ai) != 0)
139
for (p = ai; p != NULL; p = p->ai_next)
141
makiNetworkAddress me;
142
socklen_t me_len = sizeof(me.ss);
144
if (stun_usage_bind_run(p->ai_addr, p->ai_addrlen, &(me.sa), &me_len) != STUN_USAGE_BIND_RETURN_SUCCESS)
149
g_mutex_lock(net->lock);
150
net->remote.addr = me.ss;
151
net->remote.addrlen = me_len;
152
g_mutex_unlock(net->lock);
165
makiNetwork* maki_network_new (makiInstance* inst)
169
net = g_new(makiNetwork, 1);
171
net->instance = inst;
173
net->local.ip = NULL;
175
memset(&net->remote.addr, 0, sizeof(net->remote.addr));
176
net->remote.addrlen = 0;
178
net->lock = g_mutex_new();
180
#ifdef HAVE_GUPNP_IGD_1_0
181
net->upnp_igd = gupnp_simple_igd_new(NULL);
187
void maki_network_free (makiNetwork* net)
189
#ifdef HAVE_GUPNP_IGD_1_0
190
g_object_unref(net->upnp_igd);
193
g_mutex_free(net->lock);
195
g_free(net->local.ip);
200
void maki_network_update (makiNetwork* net)
202
g_return_if_fail(net != NULL);
204
i_idle_add(maki_network_update_local, net, maki_instance_main_context(net->instance));
205
i_idle_add(maki_network_update_remote, net, maki_instance_main_context(net->instance));
208
gboolean maki_network_remote_addr (makiNetwork* net, struct sockaddr* addr, socklen_t* addrlen)
210
g_return_val_if_fail(net != NULL, FALSE);
211
g_return_val_if_fail(addr != NULL, FALSE);
212
g_return_val_if_fail(addrlen != NULL, FALSE);
214
g_mutex_lock(net->lock);
216
if (*addrlen < net->remote.addrlen || net->remote.addrlen == 0)
221
memcpy(addr, &net->remote.addr, net->remote.addrlen);
222
*addrlen = net->remote.addrlen;
224
g_mutex_unlock(net->lock);
229
g_mutex_unlock(net->lock);
234
gboolean maki_network_upnp_add_port (makiNetwork* net, guint port, const gchar* description)
236
gboolean ret = FALSE;
238
g_return_val_if_fail(net != NULL, FALSE);
239
g_return_val_if_fail(port != 0, FALSE);
240
g_return_val_if_fail(description != NULL, FALSE);
242
#ifdef HAVE_GUPNP_IGD_1_0
243
g_mutex_lock(net->lock);
245
if (net->local.ip != NULL)
247
gupnp_simple_igd_add_port(net->upnp_igd, "TCP", port, net->local.ip, port, 600, description);
250
g_mutex_unlock(net->lock);
258
gboolean maki_network_upnp_remove_port (makiNetwork* net, guint port)
260
gboolean ret = FALSE;
262
g_return_val_if_fail(net != NULL, FALSE);
263
g_return_val_if_fail(port != 0, FALSE);
265
#ifdef HAVE_GUPNP_IGD_1_0
266
g_mutex_lock(net->lock);
267
gupnp_simple_igd_remove_port(net->upnp_igd, "TCP", port);
268
g_mutex_unlock(net->lock);