Mercurial > pidgin.yaz
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 |