2
0

forward.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. /*
  28. * History:
  29. * -------
  30. * 2001-??-?? created by andrei
  31. * ????-??-?? lots of changes by a lot of people
  32. * 2003-02-11 added inline msg_send (andrei)
  33. * 2003-04-07 changed all ports to host byte order (andrei)
  34. * 2003-04-12 FORCE_RPORT_T added (andrei)
  35. * 2003-04-15 added tcp_disable support (andrei)
  36. * 2006-04-12 reduced msg_send() parameter list: it uses now a struct
  37. * dest_info param. (andrei)
  38. * 2007-10-08 msg_send() will ignore a mcast send_sock and choose another
  39. * one by itself (andrei)
  40. */
  41. #ifndef forward_h
  42. #define forward_h
  43. #include "globals.h"
  44. #include "parser/msg_parser.h"
  45. #include "route.h"
  46. #include "proxy.h"
  47. #include "ip_addr.h"
  48. #include "stats.h"
  49. #include "udp_server.h"
  50. #ifdef USE_TCP
  51. #include "tcp_server.h"
  52. #include "tcp_conn.h"
  53. #endif
  54. #ifdef USE_SCTP
  55. #include "sctp_server.h"
  56. #endif
  57. #include "compiler_opt.h"
  58. #include "events.h"
  59. enum ss_mismatch {
  60. SS_MISMATCH_OK=0,
  61. SS_MISMATCH_PROTO, /* proto mismatch, but found same addr:port */
  62. SS_MISMATCH_ADDR, /* proto and addr:port mismatch */
  63. SS_MISMATCH_AF, /* af mismatch */
  64. SS_MISMATCH_MCAST /* mcast forced send socket */
  65. };
  66. struct socket_info* get_send_socket2(struct socket_info* force_send_socket,
  67. union sockaddr_union* su, int proto,
  68. enum ss_mismatch* mismatch);
  69. inline static struct socket_info* get_send_socket(struct sip_msg* msg,
  70. union sockaddr_union* su, int proto)
  71. {
  72. return get_send_socket2(msg?msg->force_send_socket:0, su, proto, 0);
  73. }
  74. struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
  75. typedef int (*check_self_f)(str* host, unsigned short port,
  76. unsigned short proto);
  77. int register_check_self_func(check_self_f f);
  78. int check_self(str* host, unsigned short port, unsigned short proto);
  79. int check_self_port(unsigned short port, unsigned short proto);
  80. int forward_request( struct sip_msg* msg, str* dst, unsigned short port,
  81. struct dest_info* send_info);
  82. int update_sock_struct_from_via( union sockaddr_union* to,
  83. struct sip_msg* msg,
  84. struct via_body* via );
  85. /* use src_ip, port=src_port if rport, via port if via port, 5060 otherwise */
  86. #define update_sock_struct_from_ip( to, msg ) \
  87. init_su((to), &(msg)->rcv.src_ip, \
  88. (((msg)->via1->rport)|| \
  89. (((msg)->msg_flags|global_req_flags)&FL_FORCE_RPORT))? \
  90. (msg)->rcv.src_port: \
  91. ((msg)->via1->port)?(msg)->via1->port: SIP_PORT )
  92. int forward_reply( struct sip_msg* msg);
  93. int forward_reply_nocb( struct sip_msg* msg);
  94. int is_check_self_func_list_set(void);
  95. /* params:
  96. * dst = struct dest_info containing:
  97. * send_sock = 0 if not known (e.g. for udp in some cases), non-0 otherwise;
  98. * if 0 or mcast a new send_sock will be automatically choosen
  99. * proto = TCP|UDP
  100. * to = destination (sockaddr_union)
  101. * id = only used on tcp, it will force sending on connection "id" if id!=0
  102. * and the connection exists, else it will send to "to"
  103. * (useful for sending replies on the same connection as the request
  104. * that generated them; use 0 if you don't want this)
  105. * buf, len = buffer
  106. * returns: 0 if ok, -1 on error*/
  107. static inline int msg_send(struct dest_info* dst, char* buf, int len)
  108. {
  109. struct dest_info new_dst;
  110. str outb;
  111. #ifdef USE_TCP
  112. int port;
  113. struct ip_addr ip;
  114. union sockaddr_union* from = NULL;
  115. union sockaddr_union local_addr;
  116. struct tcp_connection *con = NULL;
  117. struct ws_event_info wsev;
  118. int ret;
  119. #endif
  120. outb.s = buf;
  121. outb.len = len;
  122. sr_event_exec(SREV_NET_DATA_OUT, (void*)&outb);
  123. #ifdef USE_TCP
  124. if (unlikely((dst->proto == PROTO_WS
  125. #ifdef USE_TLS
  126. || dst->proto == PROTO_WSS
  127. #endif
  128. ) && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
  129. if (unlikely(dst->send_flags.f & SND_F_FORCE_SOCKET
  130. && dst->send_sock)) {
  131. local_addr = dst->send_sock->su;
  132. su_setport(&local_addr, 0); /* any local port will do */
  133. from = &local_addr;
  134. }
  135. port = su_getport(&dst->to);
  136. if (likely(port)) {
  137. su2ip_addr(&ip, &dst->to);
  138. con = tcpconn_get(dst->id, &ip, port, from, 0);
  139. }
  140. else if (likely(dst->id))
  141. con = tcpconn_get(dst->id, 0, 0, 0, 0);
  142. else {
  143. LM_CRIT("BUG: msg_send called with null_id & to\n");
  144. goto error;
  145. }
  146. if (con == NULL)
  147. {
  148. LM_WARN("TCP/TLS connection for WebSocket could not be found\n");
  149. goto error;
  150. }
  151. memset(&wsev, 0, sizeof(ws_event_info_t));
  152. wsev.type = SREV_TCP_WS_FRAME_OUT;
  153. wsev.buf = outb.s;
  154. wsev.len = outb.len;
  155. wsev.id = con->id;
  156. ret = sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
  157. tcpconn_put(con);
  158. return ret;
  159. }
  160. #endif
  161. if (likely(dst->proto==PROTO_UDP)){
  162. if (unlikely((dst->send_sock==0) ||
  163. (dst->send_sock->flags & SI_IS_MCAST))){
  164. new_dst=*dst;
  165. new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
  166. if (unlikely(new_dst.send_sock==0)){
  167. LOG(L_ERR, "msg_send: ERROR: no sending socket found\n");
  168. goto error;
  169. }
  170. dst=&new_dst;
  171. }
  172. if (unlikely(udp_send(dst, outb.s, outb.len)==-1)){
  173. STATS_TX_DROPS;
  174. LOG(L_ERR, "msg_send: ERROR: udp_send failed\n");
  175. goto error;
  176. }
  177. }
  178. #ifdef USE_TCP
  179. else if (dst->proto==PROTO_TCP){
  180. if (unlikely(tcp_disable)){
  181. STATS_TX_DROPS;
  182. LOG(L_WARN, "msg_send: WARNING: attempt to send on tcp and tcp"
  183. " support is disabled\n");
  184. goto error;
  185. }else{
  186. if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
  187. dst->send_sock)) {
  188. local_addr=dst->send_sock->su;
  189. su_setport(&local_addr, 0); /* any local port will do */
  190. from=&local_addr;
  191. }
  192. if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
  193. STATS_TX_DROPS;
  194. LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
  195. goto error;
  196. }
  197. }
  198. }
  199. #ifdef USE_TLS
  200. else if (dst->proto==PROTO_TLS){
  201. if (unlikely(tls_disable)){
  202. STATS_TX_DROPS;
  203. LOG(L_WARN, "msg_send: WARNING: attempt to send on tls and tls"
  204. " support is disabled\n");
  205. goto error;
  206. }else{
  207. if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
  208. dst->send_sock)) {
  209. local_addr=dst->send_sock->su;
  210. su_setport(&local_addr, 0); /* any local port will do */
  211. from=&local_addr;
  212. }
  213. if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
  214. STATS_TX_DROPS;
  215. LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
  216. goto error;
  217. }
  218. }
  219. }
  220. #endif /* USE_TLS */
  221. #endif /* USE_TCP */
  222. #ifdef USE_SCTP
  223. else if (dst->proto==PROTO_SCTP){
  224. if (unlikely(sctp_disable)){
  225. STATS_TX_DROPS;
  226. LOG(L_WARN, "msg_send: WARNING: attempt to send on sctp and sctp"
  227. " support is disabled\n");
  228. goto error;
  229. }else{
  230. if (unlikely(dst->send_sock==0)){
  231. new_dst=*dst;
  232. new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
  233. if (unlikely(new_dst.send_sock==0)){
  234. LOG(L_ERR, "msg_send: ERROR: no sending SCTP socket found\n");
  235. goto error;
  236. }
  237. dst=&new_dst;
  238. }
  239. if (unlikely(sctp_msg_send(dst, outb.s, outb.len)<0)){
  240. STATS_TX_DROPS;
  241. LOG(L_ERR, "msg_send: ERROR: sctp_msg_send failed\n");
  242. goto error;
  243. }
  244. }
  245. }
  246. #endif /* USE_SCTP */
  247. else{
  248. LOG(L_CRIT, "BUG: msg_send: unknown proto %d\n", dst->proto);
  249. goto error;
  250. }
  251. if(outb.s != buf)
  252. pkg_free(outb.s);
  253. return 0;
  254. error:
  255. if(outb.s != buf)
  256. pkg_free(outb.s);
  257. return -1;
  258. }
  259. #endif