comparison src/protocols/simple/simple.c @ 11383:b4cf724b64f8

[gaim-migrate @ 13610] switch to core SRV resolver committer: Tailor Script <tailor@pidgin.im>
author Thomas Butter <tbutter>
date Wed, 31 Aug 2005 09:42:11 +0000
parents e40318d2bcd8
children be776f9b1818
comparison
equal deleted inserted replaced
11382:bdeace860555 11383:b4cf724b64f8
39 #include "network.h" 39 #include "network.h"
40 #include "xmlnode.h" 40 #include "xmlnode.h"
41 41
42 #include "simple.h" 42 #include "simple.h"
43 #include "sipmsg.h" 43 #include "sipmsg.h"
44 #include "srvresolve.h" 44 #include "dnssrv.h"
45 45
46 static char *gentag() { 46 static char *gentag() {
47 return g_strdup_printf("%04d%04d", rand() & 0xFFFF, rand() & 0xFFFF); 47 return g_strdup_printf("%04d%04d", rand() & 0xFFFF, rand() & 0xFFFF);
48 } 48 }
49 49
316 sip->sendlater = 0; 316 sip->sendlater = 0;
317 } 317 }
318 318
319 319
320 static void sendlater(GaimConnection *gc, const char *buf) { 320 static void sendlater(GaimConnection *gc, const char *buf) {
321 struct getserver_return *serveradr;
322 struct simple_account_data *sip = gc->proto_data; 321 struct simple_account_data *sip = gc->proto_data;
323 int error = 0; 322 int error = 0;
324 if(!sip->connecting) { 323 if(!sip->connecting) {
325 serveradr = getserver(sip->servername, "_sip._tcp"); 324 gaim_debug_info("simple","connecting to %s port %d\n", sip->realhostname, sip->realport);
326 gaim_debug_info("simple","connecting to %s port %d", serveradr->name, serveradr->port); 325 error = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, gc);
327 error = gaim_proxy_connect(sip->account, serveradr->name, serveradr->port, send_later_cb, gc);
328 if(error) { 326 if(error) {
329 gaim_connection_error(gc, _("Couldn't create socket")); 327 gaim_connection_error(gc, _("Couldn't create socket"));
330 } 328 }
331 sip->connecting = 1; 329 sip->connecting = 1;
332 } 330 }
1120 1118
1121 static gboolean simple_ht_equals_nick(const char *nick1, const char *nick2) { 1119 static gboolean simple_ht_equals_nick(const char *nick1, const char *nick2) {
1122 return (gaim_utf8_strcasecmp(nick1, nick2) == 0); 1120 return (gaim_utf8_strcasecmp(nick1, nick2) == 0);
1123 } 1121 }
1124 1122
1123 static void srvresolved(struct srv_response *resp, int results, gpointer data) {
1124 struct simple_account_data *sip = (struct simple_account_data*) data;
1125
1126 gchar *hostname;
1127 int port = 5060;
1128
1129 int error = 0;
1130 struct sockaddr_in addr;
1131 struct hostent *h;
1132
1133 /* find the host to connect to */
1134 if(results) {
1135 hostname = g_strdup(resp->hostname);
1136 port = resp->port;
1137 g_free(resp);
1138 } else {
1139 if(!gaim_account_get_bool(sip->account, "useproxy", FALSE)) {
1140 hostname = g_strdup(sip->servername);
1141 } else {
1142 hostname = g_strdup(gaim_account_get_string(sip->account, "proxy", sip->servername));
1143 }
1144 }
1145
1146 sip->realhostname = hostname;
1147 sip->realport = port;
1148 /* TCP case */
1149 if(! sip->udp) {
1150 gaim_debug_info("simple","connecting to %s port %d\n", hostname, port);
1151 /* open tcp connection to the server */
1152 error = gaim_proxy_connect(sip->account, hostname, port, login_cb, sip->gc);
1153 if(error) {
1154 gaim_connection_error(sip->gc, _("Couldn't create socket"));
1155 }
1156
1157 /* create socket for incoming connections */
1158 sip->listenfd = gaim_network_listen_range(5060, 5080);
1159 if(sip->listenfd == -1) {
1160 gaim_connection_error(sip->gc, _("Could not create listen socket"));
1161 return;
1162 }
1163 sip->listenport = gaim_network_get_port_from_fd(sip->listenfd);
1164 gaim_input_add(sip->listenfd, GAIM_INPUT_READ, simple_newconn_cb, sip->gc);
1165 } else { /* UDP */
1166 gaim_debug_info("simple", "using udp with server %s and port %d\n", hostname, port);
1167 sip->fd = socket(AF_INET, SOCK_DGRAM, 0);
1168
1169 addr.sin_family = AF_INET;
1170 addr.sin_port = htons(5060);
1171 addr.sin_addr.s_addr = INADDR_ANY;
1172 while((bind(sip->fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) <0) && ntohs(addr.sin_port)<5160) {
1173 addr.sin_port = htons(ntohs(addr.sin_port)+1);
1174 }
1175 sip->listenport = ntohs(addr.sin_port);
1176 sip->listenfd = sip->fd;
1177
1178 gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_udp_process, sip->gc);
1179 sip->serveraddr.sin_family = AF_INET;
1180 sip->serveraddr.sin_port = htons(port);
1181
1182 h = gethostbyname(hostname);
1183 sip->serveraddr.sin_addr.s_addr = ((struct in_addr*)h->h_addr)->s_addr;
1184 sip->ip = g_strdup(gaim_network_get_my_ip(sip->listenfd));
1185 sip->resendtimeout = gaim_timeout_add(2500, (GSourceFunc)resend_timeout, sip);
1186 do_register(sip);
1187 }
1188 }
1189
1125 static void simple_login(GaimAccount *account, GaimStatus *status) 1190 static void simple_login(GaimAccount *account, GaimStatus *status)
1126 { 1191 {
1127 GaimConnection *gc; 1192 GaimConnection *gc;
1128 struct simple_account_data *sip; 1193 struct simple_account_data *sip;
1129 gchar **userserver; 1194 gchar **userserver;
1130 int error=0;
1131 struct getserver_return *serveradr;
1132 gchar *hosttoconnect; 1195 gchar *hosttoconnect;
1133 1196
1134 const char *username = gaim_account_get_username(account); 1197 const char *username = gaim_account_get_username(account);
1135 1198
1136 gc = gaim_account_get_connection(account); 1199 gc = gaim_account_get_connection(account);
1137
1138 gc->proto_data = sip = g_new0(struct simple_account_data,1); 1200 gc->proto_data = sip = g_new0(struct simple_account_data,1);
1139 sip->gc=gc; 1201 sip->gc=gc;
1140 sip->account = account; 1202 sip->account = account;
1141 sip->registerexpire = 900; 1203 sip->registerexpire = 900;
1142 sip->udp = gaim_account_get_bool(account, "udp", FALSE); 1204 sip->udp = gaim_account_get_bool(account, "udp", FALSE);
1144 gaim_connection_error(gc, _("SIP usernames may not contain whitespaces or @ symbols")); 1206 gaim_connection_error(gc, _("SIP usernames may not contain whitespaces or @ symbols"));
1145 return; 1207 return;
1146 } 1208 }
1147 1209
1148 userserver = g_strsplit(username, "@", 2); 1210 userserver = g_strsplit(username, "@", 2);
1149
1150 gaim_connection_set_display_name(gc,userserver[0]); 1211 gaim_connection_set_display_name(gc,userserver[0]);
1151 sip->username = g_strdup(userserver[0]); 1212 sip->username = g_strdup(userserver[0]);
1152 sip->servername = g_strdup(userserver[1]); 1213 sip->servername = g_strdup(userserver[1]);
1153 sip->password = g_strdup(gaim_connection_get_password(gc)); 1214 sip->password = g_strdup(gaim_connection_get_password(gc));
1154 g_strfreev(userserver); 1215 g_strfreev(userserver);
1165 hosttoconnect = g_strdup(gaim_account_get_string(account, "proxy", sip->servername)); 1226 hosttoconnect = g_strdup(gaim_account_get_string(account, "proxy", sip->servername));
1166 } 1227 }
1167 1228
1168 /* TCP case */ 1229 /* TCP case */
1169 if(! sip->udp) { 1230 if(! sip->udp) {
1170 /* search for SRV record */ 1231 gaim_srv_resolve("sip","tcp",hosttoconnect,srvresolved, sip);
1171 serveradr = getserver(hosttoconnect, "_sip._tcp");
1172 gaim_debug_info("simple","connecting to %s port %d", serveradr->name, serveradr->port);
1173
1174 /* open tcp connection to the server */
1175 error = gaim_proxy_connect(account, serveradr->name, serveradr->port, login_cb, gc);
1176 if(error) {
1177 gaim_connection_error(gc, _("Couldn't create socket"));
1178 }
1179
1180 /* create socket for incoming connections */
1181 sip->listenfd = gaim_network_listen_range(5060, 5080);
1182 if(sip->listenfd == -1) {
1183 gaim_connection_error(gc, _("Could not create listen socket"));
1184 return;
1185 }
1186 sip->listenport = gaim_network_get_port_from_fd(sip->listenfd);
1187 gaim_input_add(sip->listenfd, GAIM_INPUT_READ, simple_newconn_cb, gc);
1188 } else { /* UDP */ 1232 } else { /* UDP */
1189 /* search for SRV record */ 1233 gaim_srv_resolve("sip","udp",hosttoconnect,srvresolved, sip);
1190 struct sockaddr_in addr;
1191 struct hostent *h;
1192
1193 serveradr = getserver(hosttoconnect, "_sip._udp");
1194 gaim_debug_info("simple", "using udp with server %s and port %d", serveradr->name, serveradr->port);
1195 sip->fd = socket(AF_INET, SOCK_DGRAM, 0);
1196
1197 addr.sin_family = AF_INET;
1198 addr.sin_port = htons(5060);
1199 addr.sin_addr.s_addr = INADDR_ANY;
1200 while((bind(sip->fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) <0) && ntohs(addr.sin_port)<5160) {
1201 addr.sin_port = htons(ntohs(addr.sin_port)+1);
1202 }
1203 sip->listenport = ntohs(addr.sin_port);
1204 sip->listenfd = sip->fd;
1205
1206 gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_udp_process, gc);
1207 /* TODO - change to new SRV impl. */
1208 sip->serveraddr.sin_family = AF_INET;
1209 sip->serveraddr.sin_port = htons(serveradr->port);
1210
1211 h = gethostbyname(serveradr->name);
1212 sip->serveraddr.sin_addr.s_addr = ((struct in_addr*)h->h_addr)->s_addr;
1213 sip->ip = g_strdup(gaim_network_get_my_ip(sip->listenfd));
1214 sip->resendtimeout = gaim_timeout_add(2500, (GSourceFunc)resend_timeout, sip);
1215 do_register(sip);
1216
1217 } 1234 }
1218 g_free(hosttoconnect); 1235 g_free(hosttoconnect);
1219 1236
1220 /* register timeout callback for register / subscribe renewal */ 1237 /* register timeout callback for register / subscribe renewal */
1221 sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)register_timeout, sip); 1238 sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)register_timeout, sip);
1236 if(sip->registrar.realm) g_free(sip->registrar.realm); 1253 if(sip->registrar.realm) g_free(sip->registrar.realm);
1237 if(sip->proxy.nonce) g_free(sip->proxy.nonce); 1254 if(sip->proxy.nonce) g_free(sip->proxy.nonce);
1238 if(sip->proxy.realm) g_free(sip->proxy.realm); 1255 if(sip->proxy.realm) g_free(sip->proxy.realm);
1239 if(sip->sendlater) g_free(sip->sendlater); 1256 if(sip->sendlater) g_free(sip->sendlater);
1240 if(sip->ip) g_free(sip->ip); 1257 if(sip->ip) g_free(sip->ip);
1258 if(sip->realhostname) g_free(sip->realhostname);
1241 if(sip->registertimeout) gaim_timeout_remove(sip->registertimeout); 1259 if(sip->registertimeout) gaim_timeout_remove(sip->registertimeout);
1242 sip->servername = sip->username = sip->password = sip->registrar.nonce = sip->registrar.realm = sip->proxy.nonce = sip->proxy.realm = sip->sendlater = sip->ip = NULL; 1260 sip->servername = sip->username = sip->password = sip->registrar.nonce = sip->registrar.realm = sip->proxy.nonce = sip->proxy.realm = sip->sendlater = sip->ip = sip->realhostname = NULL;
1243 } 1261 }
1244 if(gc->proto_data) g_free(gc->proto_data); 1262 if(gc->proto_data) g_free(gc->proto_data);
1245 gc->proto_data = 0; 1263 gc->proto_data = 0;
1246 } 1264 }
1247 1265