forward.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. #define GET_URI_PORT(uri) ((uri)->port_no?(uri)->port_no:(((uri)->proto==PROTO_TLS)?SIPS_PORT:SIP_PORT))
  75. struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
  76. typedef int (*check_self_f)(str* host, unsigned short port,
  77. unsigned short proto);
  78. int register_check_self_func(check_self_f f);
  79. int check_self(str* host, unsigned short port, unsigned short proto);
  80. int check_self_port(unsigned short port, unsigned short proto);
  81. int forward_request( struct sip_msg* msg, str* dst, unsigned short port,
  82. struct dest_info* send_info);
  83. int update_sock_struct_from_via( union sockaddr_union* to,
  84. struct sip_msg* msg,
  85. struct via_body* via );
  86. /* use src_ip, port=src_port if rport, via port if via port, 5060 otherwise */
  87. #define update_sock_struct_from_ip( to, msg ) \
  88. init_su((to), &(msg)->rcv.src_ip, \
  89. (((msg)->via1->rport)|| \
  90. (((msg)->msg_flags|global_req_flags)&FL_FORCE_RPORT))? \
  91. (msg)->rcv.src_port: \
  92. ((msg)->via1->port)?(msg)->via1->port: SIP_PORT )
  93. int forward_reply( struct sip_msg* msg);
  94. int forward_reply_nocb( struct sip_msg* msg);
  95. int is_check_self_func_list_set(void);
  96. /* params:
  97. * dst = struct dest_info containing:
  98. * send_sock = 0 if not known (e.g. for udp in some cases), non-0 otherwise;
  99. * if 0 or mcast a new send_sock will be automatically choosen
  100. * proto = TCP|UDP
  101. * to = destination (sockaddr_union)
  102. * id = only used on tcp, it will force sending on connection "id" if id!=0
  103. * and the connection exists, else it will send to "to"
  104. * (useful for sending replies on the same connection as the request
  105. * that generated them; use 0 if you don't want this)
  106. * buf, len = buffer
  107. * returns: 0 if ok, -1 on error*/
  108. static inline int msg_send(struct dest_info* dst, char* buf, int len)
  109. {
  110. struct dest_info new_dst;
  111. str outb;
  112. #ifdef USE_TCP
  113. int port;
  114. struct ip_addr ip;
  115. union sockaddr_union* from = NULL;
  116. union sockaddr_union local_addr;
  117. struct tcp_connection *con = NULL;
  118. struct ws_event_info wsev;
  119. int ret;
  120. #endif
  121. outb.s = buf;
  122. outb.len = len;
  123. sr_event_exec(SREV_NET_DATA_OUT, (void*)&outb);
  124. if(outb.s==NULL) {
  125. LM_ERR("failed to update outgoing buffer\n");
  126. return -1;
  127. }
  128. #ifdef USE_TCP
  129. if (unlikely((dst->proto == PROTO_WS
  130. #ifdef USE_TLS
  131. || dst->proto == PROTO_WSS
  132. #endif
  133. ) && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
  134. if (unlikely(dst->send_flags.f & SND_F_FORCE_SOCKET
  135. && dst->send_sock)) {
  136. local_addr = dst->send_sock->su;
  137. su_setport(&local_addr, 0); /* any local port will do */
  138. from = &local_addr;
  139. }
  140. port = su_getport(&dst->to);
  141. if (likely(port)) {
  142. su2ip_addr(&ip, &dst->to);
  143. con = tcpconn_get(dst->id, &ip, port, from, 0);
  144. }
  145. else if (likely(dst->id))
  146. con = tcpconn_get(dst->id, 0, 0, 0, 0);
  147. else {
  148. LM_CRIT("BUG: msg_send called with null_id & to\n");
  149. goto error;
  150. }
  151. if (con == NULL)
  152. {
  153. LM_WARN("TCP/TLS connection for WebSocket could not be found\n");
  154. goto error;
  155. }
  156. memset(&wsev, 0, sizeof(ws_event_info_t));
  157. wsev.type = SREV_TCP_WS_FRAME_OUT;
  158. wsev.buf = outb.s;
  159. wsev.len = outb.len;
  160. wsev.id = con->id;
  161. ret = sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
  162. tcpconn_put(con);
  163. goto done;
  164. }
  165. #endif
  166. if (likely(dst->proto==PROTO_UDP)){
  167. if (unlikely((dst->send_sock==0) ||
  168. (dst->send_sock->flags & SI_IS_MCAST))){
  169. new_dst=*dst;
  170. new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
  171. if (unlikely(new_dst.send_sock==0)){
  172. LOG(L_ERR, "msg_send: ERROR: no sending socket found\n");
  173. goto error;
  174. }
  175. dst=&new_dst;
  176. }
  177. if (unlikely(udp_send(dst, outb.s, outb.len)==-1)){
  178. STATS_TX_DROPS;
  179. LOG(L_ERR, "msg_send: ERROR: udp_send failed\n");
  180. goto error;
  181. }
  182. }
  183. #ifdef USE_TCP
  184. else if (dst->proto==PROTO_TCP){
  185. if (unlikely(tcp_disable)){
  186. STATS_TX_DROPS;
  187. LOG(L_WARN, "msg_send: WARNING: attempt to send on tcp and tcp"
  188. " support is disabled\n");
  189. goto error;
  190. }else{
  191. if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
  192. dst->send_sock)) {
  193. local_addr=dst->send_sock->su;
  194. su_setport(&local_addr, 0); /* any local port will do */
  195. from=&local_addr;
  196. }
  197. if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
  198. STATS_TX_DROPS;
  199. LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
  200. goto error;
  201. }
  202. }
  203. }
  204. #ifdef USE_TLS
  205. else if (dst->proto==PROTO_TLS){
  206. if (unlikely(tls_disable)){
  207. STATS_TX_DROPS;
  208. LOG(L_WARN, "msg_send: WARNING: attempt to send on tls and tls"
  209. " support is disabled\n");
  210. goto error;
  211. }else{
  212. if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
  213. dst->send_sock)) {
  214. local_addr=dst->send_sock->su;
  215. su_setport(&local_addr, 0); /* any local port will do */
  216. from=&local_addr;
  217. }
  218. if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
  219. STATS_TX_DROPS;
  220. LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
  221. goto error;
  222. }
  223. }
  224. }
  225. #endif /* USE_TLS */
  226. #endif /* USE_TCP */
  227. #ifdef USE_SCTP
  228. else if (dst->proto==PROTO_SCTP){
  229. if (unlikely(sctp_disable)){
  230. STATS_TX_DROPS;
  231. LOG(L_WARN, "msg_send: WARNING: attempt to send on sctp and sctp"
  232. " support is disabled\n");
  233. goto error;
  234. }else{
  235. if (unlikely(dst->send_sock==0)){
  236. new_dst=*dst;
  237. new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
  238. if (unlikely(new_dst.send_sock==0)){
  239. LOG(L_ERR, "msg_send: ERROR: no sending SCTP socket found\n");
  240. goto error;
  241. }
  242. dst=&new_dst;
  243. }
  244. if (unlikely(sctp_msg_send(dst, outb.s, outb.len)<0)){
  245. STATS_TX_DROPS;
  246. LOG(L_ERR, "msg_send: ERROR: sctp_msg_send failed\n");
  247. goto error;
  248. }
  249. }
  250. }
  251. #endif /* USE_SCTP */
  252. else{
  253. LOG(L_CRIT, "BUG: msg_send: unknown proto %d\n", dst->proto);
  254. goto error;
  255. }
  256. ret = 0;
  257. done:
  258. if(outb.s != buf)
  259. pkg_free(outb.s);
  260. return ret;
  261. error:
  262. if(outb.s != buf)
  263. pkg_free(outb.s);
  264. return -1;
  265. }
  266. #endif