~ubuntu-branches/ubuntu/utopic/sushi/utopic

« back to all changes in this revision

Viewing changes to .pc/gupnp_api.patch/maki/source/network.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-02-13 12:18:45 UTC
  • Revision ID: package-import@ubuntu.com-20120213121845-15l4ym44t2tk3rky
Tags: 1.3.0+dfsg-2ubuntu1
* Add gupnp_api.patch: Fix building with current gupnp-igd. Not forwarded
  upstream, gupnp_simple_igd_new() call disappeared entirely in trunk.
  (Debian #652783)
* Rebuild against libgupnp-igd-1.0-4.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2009-2010 Michael Kuhn
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
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.
 
14
 *
 
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
 
25
 * SUCH DAMAGE.
 
26
 */
 
27
 
 
28
#include "maki.h"
 
29
 
 
30
#include "network.h"
 
31
 
 
32
#include "ilib.h"
 
33
 
 
34
#ifdef HAVE_NICE
 
35
#include <interfaces.h>
 
36
#include <stun/usages/bind.h>
 
37
#endif
 
38
 
 
39
#ifdef HAVE_GUPNP_IGD_1_0
 
40
#include <libgupnp-igd/gupnp-simple-igd.h>
 
41
#endif
 
42
 
 
43
struct maki_network
 
44
{
 
45
        makiInstance* instance;
 
46
 
 
47
        struct
 
48
        {
 
49
                gchar* ip;
 
50
        }
 
51
        local;
 
52
 
 
53
        struct
 
54
        {
 
55
                struct sockaddr_storage addr;
 
56
                socklen_t addrlen;
 
57
        }
 
58
        remote;
 
59
 
 
60
        GMutex* lock;
 
61
 
 
62
#ifdef HAVE_GUPNP_IGD_1_0
 
63
        GUPnPSimpleIgd* upnp_igd;
 
64
#endif
 
65
};
 
66
 
 
67
static gboolean maki_network_update_local (gpointer data)
 
68
{
 
69
        makiNetwork* net = data;
 
70
 
 
71
        g_mutex_lock(net->lock);
 
72
        g_free(net->local.ip);
 
73
        net->local.ip = NULL;
 
74
        g_mutex_unlock(net->lock);
 
75
 
 
76
#ifdef HAVE_NICE
 
77
        {
 
78
                GList* ips;
 
79
 
 
80
                if ((ips = nice_interfaces_get_local_ips(FALSE)) != NULL)
 
81
                {
 
82
                        GList* l;
 
83
 
 
84
                        g_mutex_lock(net->lock);
 
85
                        net->local.ip = g_strdup(ips->data);
 
86
                        g_mutex_unlock(net->lock);
 
87
 
 
88
                        for (l = ips; l != NULL; l = g_list_next(l))
 
89
                        {
 
90
                                g_free(l->data);
 
91
                        }
 
92
 
 
93
                        g_list_free(ips);
 
94
                }
 
95
        }
 
96
#endif
 
97
 
 
98
        return FALSE;
 
99
}
 
100
 
 
101
static gboolean maki_network_update_remote (gpointer data)
 
102
{
 
103
        makiNetwork* net = data;
 
104
 
 
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);
 
109
 
 
110
#ifdef HAVE_NICE
 
111
        {
 
112
                gchar* stun;
 
113
 
 
114
                struct addrinfo* ai;
 
115
                struct addrinfo* p;
 
116
                struct addrinfo hints;
 
117
 
 
118
                stun = maki_instance_config_get_string(net->instance, "network", "stun");
 
119
 
 
120
                if (stun == NULL)
 
121
                {
 
122
                        goto end;
 
123
                }
 
124
 
 
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;
 
130
 
 
131
                if (getaddrinfo(stun, "3478", NULL, &ai) != 0)
 
132
                {
 
133
                        g_free(stun);
 
134
                        goto end;
 
135
                }
 
136
 
 
137
                g_free(stun);
 
138
 
 
139
                for (p = ai; p != NULL; p = p->ai_next)
 
140
                {
 
141
                        makiNetworkAddress me;
 
142
                        socklen_t me_len = sizeof(me.ss);
 
143
 
 
144
                        if (stun_usage_bind_run(p->ai_addr, p->ai_addrlen, &(me.sa), &me_len) != STUN_USAGE_BIND_RETURN_SUCCESS)
 
145
                        {
 
146
                                continue;
 
147
                        }
 
148
 
 
149
                        g_mutex_lock(net->lock);
 
150
                        net->remote.addr = me.ss;
 
151
                        net->remote.addrlen = me_len;
 
152
                        g_mutex_unlock(net->lock);
 
153
 
 
154
                        break;
 
155
                }
 
156
 
 
157
                freeaddrinfo(ai);
 
158
        }
 
159
#endif
 
160
 
 
161
end:
 
162
        return FALSE;
 
163
}
 
164
 
 
165
makiNetwork* maki_network_new (makiInstance* inst)
 
166
{
 
167
        makiNetwork* net;
 
168
 
 
169
        net = g_new(makiNetwork, 1);
 
170
 
 
171
        net->instance = inst;
 
172
 
 
173
        net->local.ip = NULL;
 
174
 
 
175
        memset(&net->remote.addr, 0, sizeof(net->remote.addr));
 
176
        net->remote.addrlen = 0;
 
177
 
 
178
        net->lock = g_mutex_new();
 
179
 
 
180
#ifdef HAVE_GUPNP_IGD_1_0
 
181
        net->upnp_igd = gupnp_simple_igd_new(NULL);
 
182
#endif
 
183
 
 
184
        return net;
 
185
}
 
186
 
 
187
void maki_network_free (makiNetwork* net)
 
188
{
 
189
#ifdef HAVE_GUPNP_IGD_1_0
 
190
        g_object_unref(net->upnp_igd);
 
191
#endif
 
192
 
 
193
        g_mutex_free(net->lock);
 
194
 
 
195
        g_free(net->local.ip);
 
196
 
 
197
        g_free(net);
 
198
}
 
199
 
 
200
void maki_network_update (makiNetwork* net)
 
201
{
 
202
        g_return_if_fail(net != NULL);
 
203
 
 
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));
 
206
}
 
207
 
 
208
gboolean maki_network_remote_addr (makiNetwork* net, struct sockaddr* addr, socklen_t* addrlen)
 
209
{
 
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);
 
213
 
 
214
        g_mutex_lock(net->lock);
 
215
 
 
216
        if (*addrlen < net->remote.addrlen || net->remote.addrlen == 0)
 
217
        {
 
218
                goto error;
 
219
        }
 
220
 
 
221
        memcpy(addr, &net->remote.addr, net->remote.addrlen);
 
222
        *addrlen = net->remote.addrlen;
 
223
 
 
224
        g_mutex_unlock(net->lock);
 
225
 
 
226
        return TRUE;
 
227
 
 
228
error:
 
229
        g_mutex_unlock(net->lock);
 
230
 
 
231
        return FALSE;
 
232
}
 
233
 
 
234
gboolean maki_network_upnp_add_port (makiNetwork* net, guint port, const gchar* description)
 
235
{
 
236
        gboolean ret = FALSE;
 
237
 
 
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);
 
241
 
 
242
#ifdef HAVE_GUPNP_IGD_1_0
 
243
        g_mutex_lock(net->lock);
 
244
 
 
245
        if (net->local.ip != NULL)
 
246
        {
 
247
                gupnp_simple_igd_add_port(net->upnp_igd, "TCP", port, net->local.ip, port, 600, description);
 
248
        }
 
249
 
 
250
        g_mutex_unlock(net->lock);
 
251
 
 
252
        ret = TRUE;
 
253
#endif
 
254
 
 
255
        return ret;
 
256
}
 
257
 
 
258
gboolean maki_network_upnp_remove_port (makiNetwork* net, guint port)
 
259
{
 
260
        gboolean ret = FALSE;
 
261
 
 
262
        g_return_val_if_fail(net != NULL, FALSE);
 
263
        g_return_val_if_fail(port != 0, FALSE);
 
264
 
 
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);
 
269
 
 
270
        ret = TRUE;
 
271
#endif
 
272
 
 
273
        return ret;
 
274
}