• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

forward.h

00001 /*
00002  *  $Id$
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of ser, a free SIP server.
00007  *
00008  * ser is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * For a license to use the ser software under conditions
00014  * other than those described here, or to purchase support for this
00015  * software, please contact iptel.org by e-mail at the following addresses:
00016  *    info@iptel.org
00017  *
00018  * ser is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License 
00024  * along with this program; if not, write to the Free Software 
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  */
00027 /*
00028  * History:
00029  * -------
00030  *  2001-??-?? created by andrei
00031  *  ????-??-?? lots of changes by a lot of people
00032  *  2003-02-11 added inline msg_send (andrei)
00033  *  2003-04-07 changed all ports to host byte order (andrei)
00034  *  2003-04-12  FORCE_RPORT_T added (andrei)
00035  *  2003-04-15  added tcp_disable support (andrei)
00036  *  2006-04-12  reduced msg_send() parameter list: it uses now a struct 
00037  *               dest_info param. (andrei)
00038  *  2007-10-08  msg_send() will ignore a mcast send_sock and choose another
00039  *               one by itself (andrei)
00040  */
00041 
00042 
00043 
00044 #ifndef forward_h
00045 #define forward_h
00046 
00047 #include "globals.h"
00048 #include "parser/msg_parser.h"
00049 #include "route.h"
00050 #include "proxy.h"
00051 #include "ip_addr.h"
00052 
00053 #include "stats.h"
00054 #include "udp_server.h"
00055 #ifdef USE_TCP
00056 #include "tcp_server.h"
00057 #endif
00058 #ifdef USE_SCTP
00059 #include "sctp_server.h"
00060 #endif
00061 
00062 #include "compiler_opt.h"
00063 #include "events.h"
00064 
00065 
00066 enum ss_mismatch {
00067         SS_MISMATCH_OK=0,
00068         SS_MISMATCH_PROTO, /* proto mismatch, but found same addr:port */
00069         SS_MISMATCH_ADDR,  /* proto and addr:port mismatch */
00070         SS_MISMATCH_AF,    /* af mismatch */
00071         SS_MISMATCH_MCAST  /* mcast forced send socket */
00072 };
00073 
00074 struct socket_info* get_send_socket2(struct socket_info* force_send_socket,
00075                                                                         union sockaddr_union* su, int proto,
00076                                                                         enum ss_mismatch* mismatch);
00077 
00078 
00079 inline static struct socket_info* get_send_socket(struct sip_msg* msg,
00080                                                                         union sockaddr_union* su, int proto)
00081 {
00082         return get_send_socket2(msg?msg->force_send_socket:0, su, proto, 0);
00083 }
00084 
00085 
00086 struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
00087 typedef int (*check_self_f)(str* host, unsigned short port,
00088                 unsigned short proto);
00089 int register_check_self_func(check_self_f f);
00090 int check_self(str* host, unsigned short port, unsigned short proto);
00091 int check_self_port(unsigned short port, unsigned short proto);
00092 int forward_request( struct sip_msg* msg, str* dst,  unsigned short port,
00093                                                 struct dest_info* send_info);
00094 int update_sock_struct_from_via( union sockaddr_union* to,
00095                                                                  struct sip_msg* msg,
00096                                                                  struct via_body* via );
00097 
00098 /* use src_ip, port=src_port if rport, via port if via port, 5060 otherwise */
00099 #define update_sock_struct_from_ip(  to, msg ) \
00100         init_su((to), &(msg)->rcv.src_ip, \
00101                         (((msg)->via1->rport)|| \
00102                          (((msg)->msg_flags|global_req_flags)&FL_FORCE_RPORT))? \
00103                                                         (msg)->rcv.src_port: \
00104                                                         ((msg)->via1->port)?(msg)->via1->port: SIP_PORT )
00105 
00106 int forward_reply( struct sip_msg* msg);
00107 
00108 int is_check_self_func_list_set(void);
00109 
00110 
00111 /* params:
00112  * dst = struct dest_info containing:
00113  *    send_sock = 0 if not known (e.g. for udp in some cases), non-0 otherwise;
00114  *                if 0 or mcast a new send_sock will be automatically choosen
00115  *    proto = TCP|UDP
00116  *    to = destination (sockaddr_union)
00117  *    id = only used on tcp, it will force sending on connection "id" if id!=0 
00118  *         and the connection exists, else it will send to "to" 
00119  *        (useful for sending replies on  the same connection as the request
00120  *         that generated them; use 0 if you don't want this)
00121  * buf, len = buffer
00122  * returns: 0 if ok, -1 on error*/
00123 
00124 static inline int msg_send(struct dest_info* dst, char* buf, int len)
00125 {
00126         struct dest_info new_dst;
00127         str outb;
00128 #ifdef USE_TCP 
00129         union sockaddr_union* from;
00130         union sockaddr_union local_addr;
00131 #endif
00132         
00133         outb.s = buf;
00134         outb.len = len;
00135         sr_event_exec(SREV_NET_DATA_OUT, (void*)&outb);
00136         
00137         if (likely(dst->proto==PROTO_UDP)){
00138                 if (unlikely((dst->send_sock==0) || 
00139                                         (dst->send_sock->flags & SI_IS_MCAST))){
00140                         new_dst=*dst;
00141                         new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
00142                         if (unlikely(new_dst.send_sock==0)){
00143                                 LOG(L_ERR, "msg_send: ERROR: no sending socket found\n");
00144                                 goto error;
00145                         }
00146                         dst=&new_dst;
00147                 }
00148                 if (unlikely(udp_send(dst, outb.s, outb.len)==-1)){
00149                         STATS_TX_DROPS;
00150                         LOG(L_ERR, "msg_send: ERROR: udp_send failed\n");
00151                         goto error;
00152                 }
00153         }
00154 #ifdef USE_TCP
00155         else if (dst->proto==PROTO_TCP){
00156                 if (unlikely(tcp_disable)){
00157                         STATS_TX_DROPS;
00158                         LOG(L_WARN, "msg_send: WARNING: attempt to send on tcp and tcp"
00159                                         " support is disabled\n");
00160                         goto error;
00161                 }else{
00162                         from=0;
00163                         if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
00164                                                 dst->send_sock)) {
00165                                 local_addr=dst->send_sock->su;
00166                                 su_setport(&local_addr, 0); /* any local port will do */
00167                                 from=&local_addr;
00168                         }
00169                         if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
00170                                 STATS_TX_DROPS;
00171                                 LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
00172                                 goto error;
00173                         }
00174                 }
00175         }
00176 #ifdef USE_TLS
00177         else if (dst->proto==PROTO_TLS){
00178                 if (unlikely(tls_disable)){
00179                         STATS_TX_DROPS;
00180                         LOG(L_WARN, "msg_send: WARNING: attempt to send on tls and tls"
00181                                         " support is disabled\n");
00182                         goto error;
00183                 }else{
00184                         from=0;
00185                         if (unlikely((dst->send_flags.f & SND_F_FORCE_SOCKET) &&
00186                                                 dst->send_sock)) {
00187                                 local_addr=dst->send_sock->su;
00188                                 su_setport(&local_addr, 0); /* any local port will do */
00189                                 from=&local_addr;
00190                         }
00191                         if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
00192                                 STATS_TX_DROPS;
00193                                 LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
00194                                 goto error;
00195                         }
00196                 }
00197         }
00198 #endif /* USE_TLS */
00199 #endif /* USE_TCP */
00200 #ifdef USE_SCTP
00201         else if (dst->proto==PROTO_SCTP){
00202                 if (unlikely(sctp_disable)){
00203                         STATS_TX_DROPS;
00204                         LOG(L_WARN, "msg_send: WARNING: attempt to send on sctp and sctp"
00205                                         " support is disabled\n");
00206                         goto error;
00207                 }else{
00208                         if (unlikely(dst->send_sock==0)){
00209                                 new_dst=*dst;
00210                                 new_dst.send_sock=get_send_socket(0, &dst->to, dst->proto);
00211                                 if (unlikely(new_dst.send_sock==0)){
00212                                         LOG(L_ERR, "msg_send: ERROR: no sending SCTP socket found\n");
00213                                         goto error;
00214                                 }
00215                                 dst=&new_dst;
00216                         }
00217                         if (unlikely(sctp_msg_send(dst, outb.s, outb.len)<0)){
00218                                 STATS_TX_DROPS;
00219                                 LOG(L_ERR, "msg_send: ERROR: sctp_msg_send failed\n");
00220                                 goto error;
00221                         }
00222                 }
00223         }
00224 #endif /* USE_SCTP */
00225         else{
00226                         LOG(L_CRIT, "BUG: msg_send: unknown proto %d\n", dst->proto);
00227                         goto error;
00228         }
00229         if(outb.s != buf)
00230                 pkg_free(outb.s);
00231         return 0;
00232 error:
00233         if(outb.s != buf)
00234                 pkg_free(outb.s);
00235         return -1;
00236 }
00237 
00238 #endif

Generated on Tue May 22 2012 13:10:07 for SIP Router by  doxygen 1.7.1