annotate src/stun.c @ 12756:6ef1cdc26b40

[gaim-migrate @ 15103] Cleanup to STUN code. Fixed endianness. Fixed to work where sizeof(short) != 2 or sizeof(int) != 4. Close the socket when we're done with it. Instead of using a bunch of static variables, pass data around the various callbacks. Don't invoke the specified StunCallback before the initial function has returned. Deal with requerying if the STUN server has changed since last query, or the last query was unsuccessful and 5 minutes have elapsed. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Sat, 07 Jan 2006 22:10:18 +0000
parents cf0d9e207cdc
children e2f1f49fad1a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
1 /**
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
2 * @file stun.c STUN (RFC3489) Implementation
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
3 * @ingroup core
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
4 *
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
5 * gaim
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
6 *
11336
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
7 * STUN implementation inspired by jstun [http://jstun.javawi.de/]
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
8 *
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
9 * Gaim is the legal property of its developers, whose names are too numerous
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
10 * to list here. Please refer to the COPYRIGHT file distributed with this
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
11 * source distribution.
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
12 *
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
13 * This program is free software; you can redistribute it and/or modify
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
14 * it under the terms of the GNU General Public License as published by
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
15 * the Free Software Foundation; either version 2 of the License, or
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
16 * (at your option) any later version.
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
17 *
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
18 * This program is distributed in the hope that it will be useful,
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
21 * GNU General Public License for more details.
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
22 *
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
23 * You should have received a copy of the GNU General Public License
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
24 * along with this program; if not, write to the Free Software
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
26 *
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
27 */
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
28
11898
8d019c4bf454 [gaim-migrate @ 14189]
Stu Tomlinson <stu@nosnilmot.com>
parents: 11677
diff changeset
29 #include "internal.h"
8d019c4bf454 [gaim-migrate @ 14189]
Stu Tomlinson <stu@nosnilmot.com>
parents: 11677
diff changeset
30
11364
e1840eb860e7 [gaim-migrate @ 13588]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11354
diff changeset
31 #ifndef _WIN32
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
32 #include <net/if.h>
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
33 #include <sys/ioctl.h>
11364
e1840eb860e7 [gaim-migrate @ 13588]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11354
diff changeset
34 #endif
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
35
12700
cf0d9e207cdc [gaim-migrate @ 15043]
Richard Laager <rlaager@wiktel.com>
parents: 12686
diff changeset
36 /* Solaris */
cf0d9e207cdc [gaim-migrate @ 15043]
Richard Laager <rlaager@wiktel.com>
parents: 12686
diff changeset
37 #if defined (__SVR4) && defined (__sun)
cf0d9e207cdc [gaim-migrate @ 15043]
Richard Laager <rlaager@wiktel.com>
parents: 12686
diff changeset
38 #include <sys/sockio.h>
cf0d9e207cdc [gaim-migrate @ 15043]
Richard Laager <rlaager@wiktel.com>
parents: 12686
diff changeset
39 #endif
cf0d9e207cdc [gaim-migrate @ 15043]
Richard Laager <rlaager@wiktel.com>
parents: 12686
diff changeset
40
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
41 #include "debug.h"
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
42 #include "account.h"
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
43 #include "dnssrv.h"
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
44 #include "network.h"
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
45 #include "proxy.h"
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
46 #include "stun.h"
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
47 #include "prefs.h"
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
48
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
49 #define MSGTYPE_BINDINGREQUEST 0x0001
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
50 #define MSGTYPE_BINDINGRESPONSE 0x0101
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
51
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
52 #define ATTRIB_MAPPEDADDRESS 0x0001
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
53
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
54 struct stun_header {
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
55 guint16 type;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
56 guint16 len;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
57 guint32 transid[4];
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
58 };
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
59
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
60 struct stun_attrib {
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
61 guint16 type;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
62 guint16 len;
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
63 };
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
64
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
65 #ifdef NOTYET
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
66 struct stun_change {
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
67 struct stun_header hdr;
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
68 struct stun_attrib attrib;
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
69 char value[4];
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
70 };
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
71 #endif
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
72
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
73 struct stun_conn {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
74 int fd;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
75 struct sockaddr_in addr;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
76 int test;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
77 int retry;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
78 guint incb;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
79 guint timeout;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
80 struct stun_header *packet;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
81 size_t packetsize;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
82 };
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
83
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
84 static GaimStunNatDiscovery nattype = {-1, 0, "\0", NULL, 0};
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
85
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
86 static GSList *callbacks = 0;
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
87
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
88 static void close_stun_conn(struct stun_conn *sc) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
89
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
90 if (sc->incb)
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
91 gaim_input_remove(sc->incb);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
92
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
93 if (sc->timeout)
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
94 gaim_timeout_remove(sc->timeout);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
95
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
96 if (sc->fd)
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
97 close(sc->fd);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
98
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
99 g_free(sc);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
100 }
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
101
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
102 static void do_callbacks() {
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
103 while(callbacks) {
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
104 StunCallback cb = callbacks->data;
11336
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
105 if(cb)
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
106 cb(&nattype);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
107 callbacks = g_slist_remove(callbacks, cb);
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
108 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
109 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
110
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
111 static gboolean timeoutfunc(gpointer data) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
112 struct stun_conn *sc = data;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
113 if(sc->retry >= 2) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
114 gaim_debug_info("stun", "request timed out, giving up.\n");
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
115 if(sc->test == 2)
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
116 nattype.type = GAIM_STUN_NAT_TYPE_SYMMETRIC;
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
117
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
118 /* set unknown */
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
119 nattype.status = GAIM_STUN_STATUS_UNKNOWN;
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
120
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
121 nattype.lookup_time = time(NULL);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
122
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
123 /* callbacks */
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
124 do_callbacks();
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
125
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
126 /* we don't need to remove the timeout (returning FALSE) */
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
127 sc->timeout = 0;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
128 close_stun_conn(sc);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
129
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
130 return FALSE;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
131 }
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
132 gaim_debug_info("stun", "request timed out, retrying.\n");
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
133 sc->retry++;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
134 sendto(sc->fd, sc->packet, sc->packetsize, 0,
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
135 (struct sockaddr *)&(sc->addr), sizeof(struct sockaddr_in));
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
136 return TRUE;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
137 }
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
138
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
139 #ifdef NOTYET
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
140 static void do_test2(struct stun_conn *sc) {
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
141 struct stun_change data;
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
142 data.hdr.type = htons(0x0001);
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
143 data.hdr.len = 0;
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
144 data.hdr.transid[0] = rand();
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
145 data.hdr.transid[1] = ntohl(((int)'g' << 24) + ((int)'a' << 16) + ((int)'i' << 8) + (int)'m');
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
146 data.hdr.transid[2] = rand();
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
147 data.hdr.transid[3] = rand();
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
148 data.attrib.type = htons(0x003);
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
149 data.attrib.len = htons(4);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
150 data.value[3] = 6;
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
151 sc->packet = (struct stun_header*)&data;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
152 sc->packetsize = sizeof(struct stun_change);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
153 sc->retry = 0;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
154 sc->test = 2;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
155 sendto(sc->fd, sc->packet, sc->packetsize, 0, (struct sockaddr *)&(sc->addr), sizeof(struct sockaddr_in));
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
156 sc->timeout = gaim_timeout_add(500, (GSourceFunc) timeoutfunc, sc);
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
157 }
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
158 #endif
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
159
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
160 static void reply_cb(gpointer data, gint source, GaimInputCondition cond) {
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
161 struct stun_conn *sc = data;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
162 char buffer[65536];
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
163 char *tmp;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
164 int len;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
165 struct in_addr in;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
166 struct stun_attrib *attrib;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
167 struct stun_header *hdr;
11300
dd1a5969b2e5 [gaim-migrate @ 13500]
Richard Laager <rlaager@wiktel.com>
parents: 11229
diff changeset
168 struct ifconf ifc;
dd1a5969b2e5 [gaim-migrate @ 13500]
Richard Laager <rlaager@wiktel.com>
parents: 11229
diff changeset
169 struct ifreq *ifr;
dd1a5969b2e5 [gaim-migrate @ 13500]
Richard Laager <rlaager@wiktel.com>
parents: 11229
diff changeset
170 struct sockaddr_in *sinptr;
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
171
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
172 len = recv(source, buffer, sizeof(buffer) - 1, 0);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
173 if (!len) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
174 gaim_debug_info("stun", "unable to read stun response\n");
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
175 return;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
176 }
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
177 buffer[len] = '\0';
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
178
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
179 if (len < sizeof(struct stun_header)) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
180 gaim_debug_info("stun", "got invalid response\n");
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
181 return;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
182 }
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
183
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
184 hdr = (struct stun_header*) buffer;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
185 if (len != (ntohs(hdr->len) + sizeof(struct stun_header))) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
186 gaim_debug_info("stun", "got incomplete response\n");
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
187 return;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
188 }
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
189
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
190 /* wrong transaction */
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
191 if(hdr->transid[0] != sc->packet->transid[0]
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
192 || hdr->transid[1] != sc->packet->transid[1]
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
193 || hdr->transid[2] != sc->packet->transid[2]
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
194 || hdr->transid[3] != sc->packet->transid[3]) {
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
195 gaim_debug_info("stun", "got wrong transid\n");
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
196 return;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
197 }
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
198
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
199 if(sc->test==1) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
200 if (hdr->type != MSGTYPE_BINDINGRESPONSE) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
201 gaim_debug_info("stun",
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
202 "Expected Binding Response, got %d\n",
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
203 hdr->type);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
204 return;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
205 }
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
206
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
207 tmp = buffer + sizeof(struct stun_header);
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
208 while((buffer + len) > (tmp + sizeof(struct stun_attrib))) {
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
209 attrib = (struct stun_attrib*) tmp;
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
210 tmp += sizeof(struct stun_attrib);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
211
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
212 if (!((buffer + len) > (tmp + ntohs(attrib->len))))
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
213 break;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
214
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
215 if(attrib->type == htons(ATTRIB_MAPPEDADDRESS)
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
216 && ntohs(attrib->len) == 8) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
217 char *ip;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
218 /* Skip the first unused byte,
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
219 * the family(1 byte), and the port(2 bytes);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
220 * then read the 4 byte IPv4 address */
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
221 memcpy(&in.s_addr, tmp + 4, 4);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
222 ip = inet_ntoa(in);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
223 if(ip)
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
224 strcpy(nattype.publicip, ip);
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
225 }
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
226
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
227 tmp += attrib->len;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
228 }
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
229 gaim_debug_info("stun", "got public ip %s\n", nattype.publicip);
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
230 nattype.status = GAIM_STUN_STATUS_DISCOVERED;
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
231 nattype.type = GAIM_STUN_NAT_TYPE_UNKNOWN_NAT;
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
232 nattype.lookup_time = time(NULL);
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
233
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
234 /* is it a NAT? */
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
235
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
236 ifc.ifc_len = sizeof(buffer);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
237 ifc.ifc_req = (struct ifreq *) buffer;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
238 ioctl(source, SIOCGIFCONF, &ifc);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
239
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
240 tmp = buffer;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
241 while(tmp < buffer + ifc.ifc_len) {
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
242 ifr = (struct ifreq *) tmp;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
243
11364
e1840eb860e7 [gaim-migrate @ 13588]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11354
diff changeset
244 tmp += sizeof(struct ifreq);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
245
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
246 if(ifr->ifr_addr.sa_family == AF_INET) {
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
247 /* we only care about ipv4 interfaces */
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
248 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
249 if(sinptr->sin_addr.s_addr == in.s_addr) {
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
250 /* no NAT */
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
251 gaim_debug_info("stun", "no nat");
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
252 nattype.type = GAIM_STUN_NAT_TYPE_PUBLIC_IP;
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
253 }
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
254 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
255 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
256
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
257 #ifndef NOTYET
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
258 close_stun_conn(sc);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
259 do_callbacks();
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
260 #else
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
261 gaim_timeout_remove(sc->timeout);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
262 sc->timeout = 0;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
263
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
264 do_test2(sc);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
265 } else if(sc->test == 2) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
266 close_stun_conn(sc);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
267 nattype.type = GAIM_STUN_NAT_TYPE_FULL_CONE;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
268 do_callbacks();
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
269 #endif
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
270 }
11336
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
271 }
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
272
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
273 static void hbn_cb(GSList *hosts, gpointer data, const char *error_message) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
274 struct stun_conn *sc;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
275 static struct stun_header hdr_data;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
276 int ret, fd;
11425
54fa445aff32 [gaim-migrate @ 13662]
Thomas Butter <tbutter>
parents: 11424
diff changeset
277
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
278 if(!hosts || !hosts->data) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
279 nattype.status = GAIM_STUN_STATUS_UNDISCOVERED;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
280 nattype.lookup_time = time(NULL);
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
281 do_callbacks();
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
282 return;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
283 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
284
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
285
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
286 fd = gaim_network_listen_range(12108, 12208, SOCK_DGRAM);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
287
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
288 if(!fd) {
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
289 nattype.status = GAIM_STUN_STATUS_UNKNOWN;
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
290 nattype.lookup_time = time(NULL);
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
291 do_callbacks();
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
292 return;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
293 }
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
294
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
295 sc = g_new0(struct stun_conn, 1);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
296 sc->fd = fd;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
297
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
298 sc->addr.sin_family = AF_INET;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
299 sc->addr.sin_port = htons(gaim_network_get_port_from_fd(fd));
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
300 sc->addr.sin_addr.s_addr = INADDR_ANY;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
301
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
302 sc->incb = gaim_input_add(fd, GAIM_INPUT_READ, reply_cb, sc);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
303
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
304 ret = GPOINTER_TO_INT(hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
305 hosts = g_slist_remove(hosts, hosts->data);
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
306 memcpy(&(sc->addr), hosts->data, sizeof(struct sockaddr_in));
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
307 g_free(hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
308 hosts = g_slist_remove(hosts, hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
309 while(hosts) {
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
310 hosts = g_slist_remove(hosts, hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
311 g_free(hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
312 hosts = g_slist_remove(hosts, hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
313 }
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
314
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
315 hdr_data.type = htons(MSGTYPE_BINDINGREQUEST);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
316 hdr_data.len = 0;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
317 hdr_data.transid[0] = rand();
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
318 hdr_data.transid[1] = ntohl(((int)'g' << 24) + ((int)'a' << 16) + ((int)'i' << 8) + (int)'m');
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
319 hdr_data.transid[2] = rand();
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
320 hdr_data.transid[3] = rand();
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
321
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
322 if(sendto(sc->fd, &hdr_data, sizeof(struct stun_header), 0,
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
323 (struct sockaddr *)&(sc->addr),
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
324 sizeof(struct sockaddr_in)) < sizeof(struct stun_header)) {
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
325 nattype.status = GAIM_STUN_STATUS_UNKNOWN;
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
326 nattype.lookup_time = time(NULL);
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
327 do_callbacks();
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
328 close_stun_conn(sc);
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
329 return;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
330 }
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
331 sc->test = 1;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
332 sc->packet = &hdr_data;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
333 sc->packetsize = sizeof(struct stun_header);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
334 sc->timeout = gaim_timeout_add(500, (GSourceFunc) timeoutfunc, sc);
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
335 }
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
336
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
337 static void do_test1(GaimSrvResponse *resp, int results, gpointer sdata) {
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
338 const char *servername = sdata;
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
339 int port = 3478;
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
340
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
341 if(results) {
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
342 servername = resp[0].hostname;
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
343 port = resp[0].port;
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
344 }
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
345 gaim_debug_info("stun", "got %d SRV responses, server: %s, port: %d\n",
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
346 results, servername, port);
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
347
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
348 gaim_gethostbyname_async(servername, port, hbn_cb, NULL);
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
349 g_free(resp);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
350 }
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
351
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
352 static gboolean call_callback(gpointer data) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
353 StunCallback cb = data;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
354 cb(&nattype);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
355 return FALSE;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
356 }
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
357
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
358 GaimStunNatDiscovery *gaim_stun_discover(StunCallback cb) {
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
359 const char *servername = gaim_prefs_get_string("/core/network/stun_server");
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
360
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
361 gaim_debug_info("stun", "using server %s\n", servername);
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
362
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
363 if(nattype.status == GAIM_STUN_STATUS_DISCOVERING) {
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
364 if(cb)
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
365 callbacks = g_slist_append(callbacks, cb);
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
366 return &nattype;
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
367 }
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
368
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
369 if(nattype.status != GAIM_STUN_STATUS_UNDISCOVERED) {
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
370 gboolean use_cached_result = TRUE;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
371
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
372 /** Deal with the server name having changed since we did the
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
373 lookup */
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
374 if (servername && strlen(servername) > 1
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
375 && ((nattype.servername
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
376 && strcmp(servername, nattype.servername))
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
377 || !nattype.servername)) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
378 use_cached_result = FALSE;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
379 }
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
380
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
381 /* If we don't have a successful status and it has been 5
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
382 minutes since we last did a lookup, redo the lookup */
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
383 if (nattype.status != GAIM_STUN_STATUS_DISCOVERED
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
384 && (time(NULL) - nattype.lookup_time) > 300) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
385 use_cached_result = FALSE;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
386 }
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
387
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
388 if (use_cached_result) {
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
389 if(cb)
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
390 gaim_timeout_add(10, call_callback, cb);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
391 return &nattype;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
392 }
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
393 }
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
394
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
395 if(!servername || (strlen(servername) < 2)) {
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
396 nattype.status = GAIM_STUN_STATUS_UNKNOWN;
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
397 nattype.lookup_time = time(NULL);
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
398 if(cb)
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
399 gaim_timeout_add(10, call_callback, cb);
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
400 return &nattype;
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
401 }
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
402
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
403 nattype.status = GAIM_STUN_STATUS_DISCOVERING;
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
404 nattype.publicip[0] = '\0';
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
405 g_free(nattype.servername);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
406 nattype.servername = g_strdup(servername);
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
407
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
408 callbacks = g_slist_append(callbacks, cb);
12686
5f65a0cca87c [gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents: 11898
diff changeset
409 gaim_srv_resolve("stun", "udp", servername, do_test1,
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
410 (gpointer) servername);
12756
6ef1cdc26b40 [gaim-migrate @ 15103]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 12700
diff changeset
411
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
412 return &nattype;
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
413 }
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
414
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
415 void gaim_stun_init() {
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
416 gaim_prefs_add_string("/core/network/stun_server", "");
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
417 }