forward.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 Fhg Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. */
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32. #include <netdb.h>
  33. #include <netinet/in.h>
  34. #include <arpa/inet.h>
  35. #include "forward.h"
  36. #include "hash_func.h"
  37. #include "config.h"
  38. #include "parser/msg_parser.h"
  39. #include "route.h"
  40. #include "dprint.h"
  41. #include "udp_server.h"
  42. #include "globals.h"
  43. #include "data_lump.h"
  44. #include "ut.h"
  45. #include "mem/mem.h"
  46. #include "msg_translator.h"
  47. #include "sr_module.h"
  48. #include "stats.h"
  49. #include "ip_addr.h"
  50. #include "resolve.h"
  51. #include "name_alias.h"
  52. #ifdef DEBUG_DMALLOC
  53. #include <dmalloc.h>
  54. #endif
  55. /* returns a socket_info pointer to the sending socket or 0 on error
  56. * params: destination socket_union pointer
  57. */
  58. struct socket_info* get_send_socket(union sockaddr_union* to)
  59. {
  60. struct socket_info* send_sock;
  61. send_sock=0;
  62. /* check if we need to change the socket (different address families -
  63. * eg: ipv4 -> ipv6 or ipv6 -> ipv4) */
  64. if (to->s.sa_family!=bind_address->address.af){
  65. switch(to->s.sa_family){
  66. case AF_INET: send_sock=sendipv4;
  67. break;
  68. #ifdef USE_IPV6
  69. case AF_INET6: send_sock=sendipv6;
  70. break;
  71. #endif
  72. default: LOG(L_ERR, "get_send_socket: BUG: don't know how"
  73. " to forward to af %d\n", to->s.sa_family);
  74. }
  75. }else send_sock=bind_address;
  76. return send_sock;
  77. }
  78. /* checks if the host is one of the address we listen on
  79. * returns 1 if true, 0 if false, -1 on error
  80. */
  81. int check_self(str* host)
  82. {
  83. int r;
  84. for (r=0; r<sock_no; r++){
  85. DBG("check_self - checking if host==us: %d==%d && "
  86. " [%.*s] == [%.*s]\n",
  87. host->len,
  88. sock_info[r].name.len,
  89. host->len, host->s,
  90. sock_info[r].name.len, sock_info[r].name.s
  91. );
  92. if ( (host->len==sock_info[r].name.len) &&
  93. #ifdef USE_IPV6
  94. (strncasecmp(host->s, sock_info[r].name.s,
  95. sock_info[r].name.len)==0) /*slower*/
  96. #else
  97. (memcmp(host->s, sock_info[r].name.s,
  98. sock_info[r].name.len)==0)
  99. #endif
  100. )
  101. break;
  102. /* check if host == ip address */
  103. if ( (!sock_info[r].is_ip) &&
  104. (host->len==sock_info[r].address_str.len) &&
  105. #ifdef USE_IPV6
  106. (strncasecmp(host->s, sock_info[r].address_str.s,
  107. sock_info[r].address_str.len)==0) /*slower*/
  108. #else
  109. (memcmp(host->s, sock_info[r].address_str.s,
  110. sock_info[r].address_str.len)==0)
  111. #endif
  112. )
  113. break;
  114. }
  115. if (r==sock_no){
  116. /* try to look into the aliases*/
  117. if (grep_aliases(host->s, host->len)==0){
  118. DBG("check_self: host != me\n");
  119. return 0;
  120. }
  121. }
  122. return 1;
  123. }
  124. int forward_request( struct sip_msg* msg, struct proxy_l * p)
  125. {
  126. unsigned int len;
  127. char* buf;
  128. union sockaddr_union* to;
  129. struct socket_info* send_sock;
  130. char md5[MD5_LEN];
  131. to=0;
  132. buf=0;
  133. to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
  134. if (to==0){
  135. ser_error=E_OUT_OF_MEM;
  136. LOG(L_ERR, "ERROR: forward_request: out of memory\n");
  137. goto error;
  138. }
  139. /* if error try next ip address if possible */
  140. if (p->ok==0){
  141. if (p->host.h_addr_list[p->addr_idx+1])
  142. p->addr_idx++;
  143. else p->addr_idx=0;
  144. p->ok=1;
  145. }
  146. hostent2su(to, &p->host, p->addr_idx,
  147. (p->port)?htons(p->port):htons(SIP_PORT));
  148. p->tx++;
  149. p->tx_bytes+=len;
  150. send_sock=get_send_socket(to);
  151. if (send_sock==0){
  152. LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d "
  153. "no coresponding listening socket\n", to->s.sa_family);
  154. ser_error=E_NO_SOCKET;
  155. goto error1;
  156. }
  157. /* calculate branch for outbound request; if syn_branch is turned off,
  158. calculate is from transaction key, i.e., as an md5 of From/To/CallID/
  159. CSeq exactly the same way as TM does; good for reboot -- than messages
  160. belonging to transaction lost due to reboot will still be forwarded
  161. with the same branch parameter and will be match-able downstream
  162. if it is turned on, we don't care about reboot; we simply put a simple
  163. value in there; better for performance
  164. */
  165. if (syn_branch ) {
  166. *msg->add_to_branch_s='0';
  167. msg->add_to_branch_len=1;
  168. } else {
  169. if (!char_msg_val( msg, md5 )) { /* parses transaction key */
  170. LOG(L_ERR, "ERROR: forward_request: char_msg_val failed\n");
  171. goto error1;
  172. }
  173. msg->hash_index=hash( msg->callid->body, get_cseq(msg)->number);
  174. if (!branch_builder( msg->hash_index, 0, md5, 0 /* 0-th branch */,
  175. msg->add_to_branch_s, &msg->add_to_branch_len )) {
  176. LOG(L_ERR, "ERROR: forward_request: branch_builder failed\n");
  177. goto error1;
  178. }
  179. }
  180. buf = build_req_buf_from_sip_req( msg, &len, send_sock);
  181. if (!buf){
  182. LOG(L_ERR, "ERROR: forward_request: building failed\n");
  183. goto error1;
  184. }
  185. /* send it! */
  186. DBG("Sending:\n%s.\n", buf);
  187. DBG("orig. len=%d, new_len=%d\n", msg->len, len );
  188. if (udp_send(send_sock, buf, len, to)==-1){
  189. ser_error=E_SEND;
  190. p->errors++;
  191. p->ok=0;
  192. STATS_TX_DROPS;
  193. goto error1;
  194. }
  195. /* sent requests stats */
  196. else STATS_TX_REQUEST( msg->first_line.u.request.method_value );
  197. pkg_free(buf);
  198. free(to);
  199. /* received_buf & line_buf will be freed in receiv_msg by free_lump_list*/
  200. return 0;
  201. error1:
  202. free(to);
  203. error:
  204. if (buf) pkg_free(buf);
  205. return -1;
  206. }
  207. int update_sock_struct_from_ip( union sockaddr_union* to,
  208. struct sip_msg *msg )
  209. {
  210. to->sin.sin_port=(msg->via1->port)
  211. ?htons(msg->via1->port): htons(SIP_PORT);
  212. to->sin.sin_family=msg->src_ip.af;
  213. memcpy(&to->sin.sin_addr, &msg->src_ip.u, msg->src_ip.len);
  214. return 1;
  215. }
  216. int update_sock_struct_from_via( union sockaddr_union* to,
  217. struct via_body* via )
  218. {
  219. struct hostent* he;
  220. char *host_copy;
  221. str* name;
  222. unsigned short port;
  223. if (via->received){
  224. DBG("update_sock_struct_from_via: using 'received'\n");
  225. name=&(via->received->value);
  226. /* making sure that we won't do SRV lookup on "received"
  227. * (possible if no DNS_IP_HACK is used)*/
  228. port=via->port?via->port:SIP_PORT;
  229. }else{
  230. DBG("update_sock_struct_from_via: using via host\n");
  231. name=&(via->host);
  232. port=via->port;
  233. }
  234. /* we do now a malloc/memcpy because gethostbyname loves \0-terminated
  235. strings; -jiri
  236. but only if host is not null terminated
  237. (host.s[len] will always be ok for a via)
  238. BTW: when is via->host.s non null terminated? tm copy? - andrei
  239. Yes -- it happened on generating a 408 by TM; -jiri
  240. */
  241. if (name->s[name->len]){
  242. host_copy=pkg_malloc( name->len+1 );
  243. if (!host_copy) {
  244. LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
  245. " not enough memory\n");
  246. return -1;
  247. }
  248. memcpy(host_copy, name->s, name->len );
  249. host_copy[name->len]=0;
  250. DBG("update_sock_struct_from_via: trying SRV lookup\n");
  251. he=sip_resolvehost(host_copy, &port);
  252. pkg_free( host_copy );
  253. }else{
  254. DBG("update_sock_struct_from_via: trying SRV lookup\n");
  255. he=sip_resolvehost(name->s, &port);
  256. }
  257. if (he==0){
  258. LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
  259. name->s);
  260. return -1;
  261. }
  262. hostent2su(to, he, 0, htons(port));
  263. return 1;
  264. }
  265. /* removes first via & sends msg to the second */
  266. int forward_reply(struct sip_msg* msg)
  267. {
  268. char* new_buf;
  269. union sockaddr_union* to;
  270. struct socket_info* send_sock;
  271. unsigned int new_len;
  272. struct sr_module *mod;
  273. to=0;
  274. new_buf=0;
  275. /*check if first via host = us */
  276. if (check_via){
  277. if (check_self(&(msg->via1->host))!=1){
  278. LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :"
  279. " %.*s\n", msg->via1->host.len, msg->via1->host.s);
  280. /* send error msg back? */
  281. goto error;
  282. }
  283. }
  284. /* quick hack, slower for mutliple modules*/
  285. for (mod=modules;mod;mod=mod->next){
  286. if ((mod->exports) && (mod->exports->response_f)){
  287. DBG("forward_reply: found module %s, passing reply to it\n",
  288. mod->exports->name);
  289. if (mod->exports->response_f(msg)==0) goto skip;
  290. }
  291. }
  292. /* we have to forward the reply stateless, so we need second via -bogdan*/
  293. if (parse_headers( msg, HDR_VIA2, 0 )==-1
  294. || (msg->via2==0) || (msg->via2->error!=PARSE_OK))
  295. {
  296. /* no second via => error */
  297. LOG(L_ERR, "ERROR: forward_msg: no 2nd via found in reply\n");
  298. goto error;
  299. }
  300. to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
  301. if (to==0){
  302. LOG(L_ERR, "ERROR: forward_reply: out of memory\n");
  303. goto error;
  304. }
  305. new_buf = build_res_buf_from_sip_res( msg, &new_len);
  306. if (!new_buf){
  307. LOG(L_ERR, "ERROR: forward_reply: building failed\n");
  308. goto error;
  309. }
  310. if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
  311. send_sock=get_send_socket(to);
  312. if (send_sock==0){
  313. LOG(L_ERR, "forward_reply: ERROR: no sending socket found\n");
  314. goto error;
  315. }
  316. if (udp_send(send_sock, new_buf,new_len, to)==-1)
  317. {
  318. STATS_TX_DROPS;
  319. goto error;
  320. } else {
  321. #ifdef STATS
  322. int j = msg->first_line.u.reply.statuscode/100;
  323. STATS_TX_RESPONSE( j );
  324. #endif
  325. }
  326. DBG(" reply forwarded to %s:%d\n",msg->via2->host.s,
  327. (unsigned short) msg->via2->port);
  328. pkg_free(new_buf);
  329. free(to);
  330. skip:
  331. return 0;
  332. error:
  333. if (new_buf) pkg_free(new_buf);
  334. if (to) free(to);
  335. return -1;
  336. }