forward.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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_core.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. void forward_set_send_info(int v);
  96. int is_check_self_func_list_set(void);
  97. /* params:
  98. * dst = struct dest_info containing:
  99. * send_sock = 0 if not known (e.g. for udp in some cases), non-0 otherwise;
  100. * if 0 or mcast a new send_sock will be automatically choosen
  101. * proto = TCP|UDP
  102. * to = destination (sockaddr_union)
  103. * id = only used on tcp, it will force sending on connection "id" if id!=0
  104. * and the connection exists, else it will send to "to"
  105. * (useful for sending replies on the same connection as the request
  106. * that generated them; use 0 if you don't want this)
  107. * buf, len = buffer
  108. * returns: 0 if ok, -1 on error*/
  109. static inline int msg_send(struct dest_info* dst, char* buf, int len)
  110. {
  111. struct dest_info new_dst;
  112. str outb;
  113. #ifdef USE_TCP
  114. int port;
  115. struct ip_addr ip;
  116. union sockaddr_union* from = NULL;
  117. union sockaddr_union local_addr;
  118. struct tcp_connection *con = NULL;
  119. struct ws_event_info wsev;
  120. int ret;
  121. #endif
  122. outb.s = buf;
  123. outb.len = len;
  124. sr_event_exec(SREV_NET_DATA_OUT, (void*)&outb);
  125. if(outb.s==NULL) {
  126. LM_ERR("failed to update outgoing buffer\n");
  127. return -1;
  128. }
  129. #ifdef USE_TCP
  130. if (unlikely((dst->proto == PROTO_WS
  131. #ifdef USE_TLS
  132. || dst->proto == PROTO_WSS
  133. #endif
  134. ) && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
  135. if (unlikely(dst->send_flags.f & SND_F_FORCE_SOCKET
  136. && dst->send_sock)) {
  137. local_addr = dst->send_sock->su;
  138. su_setport(&local_addr, 0); /* any local port will do */
  139. from = &local_addr;
  140. }
  141. port = su_getport(&dst->to);
  142. if (likely(port)) {
  143. su2ip_addr(&ip, &dst->to);
  144. con = tcpconn_get(dst->id, &ip, port, from, 0);
  145. }
  146. else if (likely(dst->id))
  147. con = tcpconn_get(dst->id, 0, 0, 0, 0);
  148. else {
  149. LM_CRIT("null_id & to\n");
  150. goto error;
  151. }
  152. if (con == NULL)
  153. {
  154. LM_WARN("TCP/TLS connection for WebSocket could not be found\n");
  155. goto error;
  156. }
  157. memset(&wsev, 0, sizeof(ws_event_info_t));
  158. wsev.type = SREV_TCP_WS_FRAME_OUT;
  159. wsev.buf = outb.s;
  160. wsev.len = outb.len;
  161. wsev.id = con->id;
  162. ret = sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
  163. tcpconn_put(con);
  164. goto done;
  165. }
  166. #endif
  167. if (likely(dst->proto==PROTO_UDP)){
  168. if (unlikely((dst->send_sock==0) ||
  169. (dst->send_sock->flags & SI_IS_MCAST))){
  170. new_dst=*dst;
  171. new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
  172. if (unlikely(new_dst.send_sock==0)){
  173. LM_ERR("no sending socket found\n");
  174. goto error;
  175. }
  176. dst=&new_dst;
  177. }
  178. if (unlikely(udp_send(dst, outb.s, outb.len)==-1)){
  179. STATS_TX_DROPS;
  180. LM_ERR("udp_send failed\n");
  181. goto error;
  182. }
  183. }
  184. #ifdef USE_TCP
  185. else if (dst->proto==PROTO_TCP){
  186. if (unlikely(tcp_disable)){
  187. STATS_TX_DROPS;
  188. LM_WARN("attempt to send on tcp and tcp 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. LM_ERR("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. LM_WARN("attempt to send on tls and tls support is disabled\n");
  209. goto error;
  210. }else{
  211. if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
  212. dst->send_sock)) {
  213. local_addr=dst->send_sock->su;
  214. su_setport(&local_addr, 0); /* any local port will do */
  215. from=&local_addr;
  216. }
  217. if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
  218. STATS_TX_DROPS;
  219. LM_ERR("tcp_send failed\n");
  220. goto error;
  221. }
  222. }
  223. }
  224. #endif /* USE_TLS */
  225. #endif /* USE_TCP */
  226. #ifdef USE_SCTP
  227. else if (dst->proto==PROTO_SCTP){
  228. if (unlikely(sctp_disable)){
  229. STATS_TX_DROPS;
  230. LM_WARN("attempt to send on sctp and sctp support is disabled\n");
  231. goto error;
  232. }else{
  233. if (unlikely(dst->send_sock==0)){
  234. new_dst=*dst;
  235. new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
  236. if (unlikely(new_dst.send_sock==0)){
  237. LM_ERR("no sending SCTP socket found\n");
  238. goto error;
  239. }
  240. dst=&new_dst;
  241. }
  242. if (unlikely(sctp_core_msg_send(dst, outb.s, outb.len)<0)){
  243. STATS_TX_DROPS;
  244. LM_ERR("sctp_msg_send failed\n");
  245. goto error;
  246. }
  247. }
  248. }
  249. #endif /* USE_SCTP */
  250. else{
  251. LM_CRIT("unknown proto %d\n", dst->proto);
  252. goto error;
  253. }
  254. ret = 0;
  255. done:
  256. if(outb.s != buf)
  257. pkg_free(outb.s);
  258. return ret;
  259. error:
  260. if(outb.s != buf)
  261. pkg_free(outb.s);
  262. return -1;
  263. }
  264. #endif