annotate src/stun.c @ 12116:e75ef7aa913e

[gaim-migrate @ 14416] " This patch implements a replacement for the queuing system from 1.x. It also obsoletes a previous patch [#1338873] I submitted to prioritize the unseen states in gtk conversations. The attached envelope.png is ripped from the msgunread.png already included in gaim. It should be dropped in the pixmaps directory (Makefile.am is updated accordingly in this patch). The two separate queuing preferences from 1.x, queuing messages while away and queuing all new messages (from docklet), are replaced with a single 3-way preference for conversations. The new preference is "Hide new IM conversations". This preference can be set to never, away and always. When a gtk conversation is created, it may be placed in a hidden conversation window instead of being placed normally. This decision is based upon the preference and possibly the away state of the account the conversation is being created for. This *will* effect conversations the user explicitly requests to be created, so in these cases the caller must be sure to present the conversation to the user, using gaim_gtkconv_present_conversation(). This is done already in gtkdialogs.c which handles creating conversations requested by the user from gaim proper (menus, double-clicking on budy in blist, etc.). The main advantage to not queuing messages is that the conversations exist, the message is written to the conversation (and logged if appropriate) and the unseen state is set on the conversation. This means no additional features are needed to track whether there are queued messages or not, just use the unseen state on conversations. Since conversations may not be visible (messages "queued"), gaim proper needs some notification that there are messages waiting. I opted for a menutray icon that shows up when an im conversation has an unseen message. Clicking this icon will focus (and show if hidden) the first conversation with an unseen message. This is essentially the same behavior of the docklet in cvs right now, except that the icon is only visible when there is a conversation with an unread message. The api that is added is flexible enough to allow either the docklet or the new blist menutray icon to be visible for conversations of any/all types and for unseen messages >= any state. Currently they are set to only IM conversations and only unseen states >= TEXT (system messages and no log messages will not trigger blinking the docklet or showing the blist tray icon), but these could be made preferences relatively easily in the future. Other plugins could probably benefit as well: gaim_gtk_conversations_get_first_unseen(). There is probably some limit to comment size, so I'll stop rambling now. If anyone has more questions/comments, catch me in #gaim, here or on gaim-devel." committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Wed, 16 Nov 2005 18:17:01 +0000
parents 8d019c4bf454
children 5f65a0cca87c
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
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
36 #include "debug.h"
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
37 #include "account.h"
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
38 #include "dnssrv.h"
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
39 #include "proxy.h"
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
40 #include "stun.h"
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
41 #include "prefs.h"
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
42
11677
8004885fabbe [gaim-migrate @ 13963]
Mark Doliner <mark@kingant.net>
parents: 11629
diff changeset
43 static struct stun_nattype nattype = {-1, 0, "\0"};
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
44
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
45 static GSList *callbacks = 0;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
46 static int fd = -1;
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
47 static gint incb = -1;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
48 static gint timeout = -1;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
49 static struct stun_header *packet;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
50 static int packetsize = 0;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
51 static int test = 0;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
52 static int retry = 0;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
53 static struct sockaddr_in addr;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
54
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
55 static void do_callbacks() {
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
56 while(callbacks) {
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
57 StunCallback cb = callbacks->data;
11336
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
58 if(cb)
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
59 cb(&nattype);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
60 callbacks = g_slist_remove(callbacks, cb);
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
61 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
62 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
63
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
64 static gboolean timeoutfunc(void *blah) {
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
65 if(retry > 2) {
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
66 if(test == 2) nattype.type = 5;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
67 /* remove input */
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
68 gaim_input_remove(incb);
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
69
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
70 /* set unknown */
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
71 nattype.status = 0;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
72
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
73 /* callbacks */
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
74 do_callbacks();
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
75
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
76 return FALSE;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
77 }
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
78 retry++;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
79 sendto(fd, packet, packetsize, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
80 return TRUE;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
81 }
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
82
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
83 #ifdef NOTYET
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
84 static void do_test2() {
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
85 struct stun_change data;
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
86 data.hdr.type = htons(0x0001);
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
87 data.hdr.len = 0;
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
88 data.hdr.transid[0] = rand();
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
89 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
90 data.hdr.transid[2] = rand();
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
91 data.hdr.transid[3] = rand();
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
92 data.attrib.type = htons(0x003);
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
93 data.attrib.len = htons(4);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
94 data.value[3] = 6;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
95 packet = (struct stun_header*)&data;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
96 packetsize = sizeof(struct stun_change);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
97 retry = 0;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
98 test = 2;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
99 sendto(fd, packet, packetsize, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
100 timeout = gaim_timeout_add(500, (GSourceFunc)timeoutfunc, NULL);
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
101 }
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
102 #endif
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
103
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
104 static void reply_cb(gpointer data, gint source, GaimInputCondition cond) {
11336
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
105 char buffer[1024];
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
106 char *tmp;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
107 int len;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
108 struct in_addr in;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
109 struct stun_attrib *attrib;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
110 struct stun_header *hdr;
11300
dd1a5969b2e5 [gaim-migrate @ 13500]
Richard Laager <rlaager@wiktel.com>
parents: 11229
diff changeset
111 struct ifconf ifc;
dd1a5969b2e5 [gaim-migrate @ 13500]
Richard Laager <rlaager@wiktel.com>
parents: 11229
diff changeset
112 struct ifreq *ifr;
dd1a5969b2e5 [gaim-migrate @ 13500]
Richard Laager <rlaager@wiktel.com>
parents: 11229
diff changeset
113 struct sockaddr_in *sinptr;
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
114
11336
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
115 len = recv(source, buffer, 1024, 0);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
116
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
117 hdr = (struct stun_header*)buffer;
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
118 if(hdr->transid[0]!=packet->transid[0] || hdr->transid[1]!=packet->transid[1] || hdr->transid[2]!=packet->transid[2] || hdr->transid[3]!=packet->transid[3]) { /* wrong transaction */
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
119 gaim_debug_info("stun", "got wrong transid\n");
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
120 return;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
121 }
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
122 if(test==1) {
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
123 tmp = buffer + sizeof(struct stun_header);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
124 while(buffer+len > tmp) {
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
125
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
126 attrib = (struct stun_attrib*) tmp;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
127 if(attrib->type == htons(0x0001) && attrib->len == htons(8)) {
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
128 memcpy(&in.s_addr, tmp+sizeof(struct stun_attrib)+2+2, 4);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
129 strcpy(nattype.publicip, inet_ntoa(in));
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
130 }
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
131 tmp += sizeof(struct stun_attrib) + attrib->len;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
132 }
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
133 gaim_debug_info("stun", "got public ip %s\n", nattype.publicip);
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
134 nattype.status = 2;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
135 nattype.type = 1;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
136
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
137 /* is it a NAT? */
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
138
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
139 ifc.ifc_len = sizeof(buffer);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
140 ifc.ifc_req = (struct ifreq *) buffer;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
141 ioctl(source, SIOCGIFCONF, &ifc);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
142
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
143 tmp = buffer;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
144 while(tmp < buffer + ifc.ifc_len) {
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
145 ifr = (struct ifreq *) tmp;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
146
11364
e1840eb860e7 [gaim-migrate @ 13588]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11354
diff changeset
147 tmp += sizeof(struct ifreq);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
148
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
149 if(ifr->ifr_addr.sa_family == AF_INET) {
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
150 /* we only care about ipv4 interfaces */
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
151 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
152 if(sinptr->sin_addr.s_addr == in.s_addr) {
11371
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
153 /* no NAT */
6e02e20e3a58 [gaim-migrate @ 13596]
Richard Laager <rlaager@wiktel.com>
parents: 11364
diff changeset
154 gaim_debug_info("stun", "no nat");
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
155 nattype.type = 0;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
156 }
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
157 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
158 }
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
159 gaim_timeout_remove(timeout);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
160
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
161 #ifdef NOTYET
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
162 do_test2();
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
163 #endif
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
164 return;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
165 } else if(test == 2) {
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
166 do_callbacks();
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
167 gaim_input_remove(incb);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
168 gaim_timeout_remove(timeout);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
169 nattype.type = 2;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
170 }
11336
7d7dd22215ec [gaim-migrate @ 13549]
Thomas Butter <tbutter>
parents: 11300
diff changeset
171 }
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
172
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
173 static void hbn_cb(GSList *hosts, gpointer edata, const char *error_message) {
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
174 static struct stun_header data;
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
175 int ret;
11425
54fa445aff32 [gaim-migrate @ 13662]
Thomas Butter <tbutter>
parents: 11424
diff changeset
176
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
177 if(!hosts) return;
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
178 if(!hosts->data) return;
11425
54fa445aff32 [gaim-migrate @ 13662]
Thomas Butter <tbutter>
parents: 11424
diff changeset
179
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
180 if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
181 nattype.status = 0;
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
182 do_callbacks();
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
183 return;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
184 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
185
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
186 addr.sin_family = AF_INET;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
187 addr.sin_port = htons(12108);
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
188 addr.sin_addr.s_addr = INADDR_ANY;
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
189 while( ((ret = bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) < 0 ) && ntohs(addr.sin_port) < 12208) {
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
190 addr.sin_port = htons(ntohs(addr.sin_port)+1);
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
191 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
192 if( ret < 0 ) {
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
193 nattype.status = 0;
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
194 do_callbacks();
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
195 return;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
196 }
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
197 incb = gaim_input_add(fd, GAIM_INPUT_READ, reply_cb, NULL);
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
198
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
199 ret = GPOINTER_TO_INT(hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
200 hosts = g_slist_remove(hosts, hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
201 memcpy(&addr, hosts->data, sizeof(struct sockaddr_in));
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
202 g_free(hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
203 hosts = g_slist_remove(hosts, hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
204 while(hosts) {
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
205 hosts = g_slist_remove(hosts, hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
206 g_free(hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
207 hosts = g_slist_remove(hosts, hosts->data);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
208 }
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
209
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
210 data.type = htons(0x0001);
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
211 data.len = 0;
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
212 data.transid[0] = rand();
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
213 data.transid[1] = ntohl(((int)'g' << 24) + ((int)'a' << 16) + ((int)'i' << 8) + (int)'m');
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
214 data.transid[2] = rand();
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
215 data.transid[3] = rand();
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
216
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
217 if( sendto(fd, &data, sizeof(struct stun_header), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < sizeof(struct stun_header)) {
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
218 nattype.status = 0;
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
219 do_callbacks();
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
220 return;
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
221 }
11354
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
222 test = 1;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
223 packet = &data;
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
224 packetsize = sizeof(struct stun_header);
97028c1c69e9 [gaim-migrate @ 13573]
Thomas Butter <tbutter>
parents: 11336
diff changeset
225 timeout = gaim_timeout_add(500, (GSourceFunc)timeoutfunc, NULL);
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
226 }
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
227
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
228 static void do_test1(struct srv_response *resp, int results, gpointer sdata) {
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
229 const char *servername = sdata;
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
230 int port = 3478;
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
231
11429
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
232 if(results) {
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
233 servername = resp[0].hostname;
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
234 port = resp[0].port;
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
235 }
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
236 gaim_debug_info("stun", "got %d SRV responses, server: %s, port: %d\n", results, servername, port);
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
237
835dbb1b3337 [gaim-migrate @ 13666]
Thomas Butter <tbutter>
parents: 11425
diff changeset
238 gaim_gethostbyname_async(servername, port, hbn_cb, NULL);
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
239 g_free(resp);
11225
46facec74fc1 [gaim-migrate @ 13361]
Thomas Butter <tbutter>
parents:
diff changeset
240 }
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
241
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
242 struct stun_nattype *gaim_stun_discover(StunCallback cb) {
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
243 const char *servername = gaim_prefs_get_string("/core/network/stun_server");
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
244
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
245 gaim_debug_info("stun", "using server %s\n", servername);
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
246 if(nattype.status == 1) { /* currently discovering */
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
247 if(cb) callbacks = g_slist_append(callbacks, cb);
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
248 return NULL;
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
249 }
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
250 if(nattype.status != -1) { /* already discovered */
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
251 if(cb) cb(&nattype);
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
252 return &nattype;
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
253 }
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
254
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
255 if(!servername || (strlen(servername)<2)) {
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
256 nattype.status = 0;
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
257 if(cb) cb(&nattype);
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
258 return &nattype;
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
259 }
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
260 callbacks = g_slist_append(callbacks, cb);
11431
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
261 gaim_srv_resolve("stun","udp",servername, do_test1,
d2e44c8085e0 [gaim-migrate @ 13668]
Daniel Atallah <daniel.atallah@gmail.com>
parents: 11429
diff changeset
262 (gpointer) servername);
11424
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
263 return &nattype;
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
264 }
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
265
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
266 void gaim_stun_init() {
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
267 gaim_prefs_add_string("/core/network/stun_server", "");
e1ab173ef3b5 [gaim-migrate @ 13661]
Thomas Butter <tbutter>
parents: 11371
diff changeset
268 }