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