Module: sip-router Branch: master Commit: 9981e48a4f9517c016402897e6b90916d5f64eb2 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9981e48a...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Mon Jul 20 23:51:27 2009 +0200
core: enhanced get_send_socket() version
get_send_socket2() added.
---
forward.c | 53 ++++++++++++++++++++++++++++++++++------------------- forward.h | 21 +++++++++++++++++++-- 2 files changed, 53 insertions(+), 21 deletions(-)
diff --git a/forward.c b/forward.c index 3a9cb0c..b9e8ead 100644 --- a/forward.c +++ b/forward.c @@ -151,43 +151,58 @@ error:
-/* returns a socket_info pointer to the sending socket or 0 on error - * params: sip msg (can be null), destination socket_union pointer, protocol - * if msg!=null and msg->force_send_socket, the force_send_socket will be - * used +/** get the sending socket for a corresponding destination. + * @param force_send_socket - if !=0 and the protocol and af correspond + * with the destination, it will be returned. + * If the protocol or af check fail, a look-alike + * socket will be searched for and mismatch will be + * set. If no look-alike socket is found it will + * fallback to normal resolution. + * @param to - destination + * @param proto - protocol + * @param mismatch - result parameter, set if a force_send_socket was used, but + * there was an error matching it exactly to the destination. + * Possible values: 0 ok, SS_MISMATCH_PROTO, + * SS_MISMATCH_ADDR, SS_MISMATCH_AF, SS_MISMATCH_MCAST. + * @return a socket_info pointer to the sending socket on success (and possibly + * sets mismatch) or 0 on error. */ -struct socket_info* get_send_socket(struct sip_msg *msg, - union sockaddr_union* to, int proto) +struct socket_info* get_send_socket2(struct socket_info* force_send_socket, + union sockaddr_union* to, int proto, + enum ss_mismatch* mismatch) { struct socket_info* send_sock; + if (likely(mismatch)) *mismatch=0; /* check if send interface is not forced */ - if (unlikely(msg && msg->force_send_socket)){ - if (unlikely(msg->force_send_socket->proto!=proto)){ - DBG("get_send_socket: force_send_socket of different proto" - " (%d)!\n", proto); - msg->force_send_socket=find_si(&(msg->force_send_socket->address), - msg->force_send_socket->port_no, + if (unlikely(force_send_socket)){ + if (unlikely(force_send_socket->proto!=proto)){ + force_send_socket=find_si(&(force_send_socket->address), + force_send_socket->port_no, proto); - if (unlikely(msg->force_send_socket == 0)){ + if (unlikely(force_send_socket == 0)){ + if (likely(mismatch)) *mismatch=SS_MISMATCH_ADDR; LOG(L_WARN, "WARNING: get_send_socket: " "protocol/port mismatch\n"); goto not_forced; } + if (likely(mismatch)) *mismatch=SS_MISMATCH_PROTO; } - if (unlikely(msg->force_send_socket->address.af!=to->s.sa_family)){ + if (unlikely(force_send_socket->address.af!=to->s.sa_family)){ DBG("get_send_socket: force_send_socket of different af (dst %d," " forced %d)\n", - to->s.sa_family, msg->force_send_socket->address.af); + to->s.sa_family, force_send_socket->address.af); + if (likely(mismatch)) *mismatch=SS_MISMATCH_AF; goto not_forced; } - if (likely((msg->force_send_socket->socket!=-1) && - !(msg->force_send_socket->flags & SI_IS_MCAST))) - return msg->force_send_socket; + if (likely((force_send_socket->socket!=-1) && + !(force_send_socket->flags & SI_IS_MCAST))) + return force_send_socket; else{ - if (!(msg->force_send_socket->flags & SI_IS_MCAST)) + if (!(force_send_socket->flags & SI_IS_MCAST)) LOG(L_WARN, "WARNING: get_send_socket: not listening" " on the requested socket, no fork mode?\n"); + else if (likely(mismatch)) *mismatch=SS_MISMATCH_MCAST; } }; not_forced: diff --git a/forward.h b/forward.h index f30703b..0a5750a 100644 --- a/forward.h +++ b/forward.h @@ -62,9 +62,26 @@ #include "compiler_opt.h"
+enum ss_mismatch { + SS_MISMATCH_OK=0, + SS_MISMATCH_PROTO, /* proto mismatch, but found same addr:port */ + SS_MISMATCH_ADDR, /* proto and addr:port mismatch */ + SS_MISMATCH_AF, /* af mismatch */ + SS_MISMATCH_MCAST /* mcast forced send socket */ +}; + +struct socket_info* get_send_socket2(struct socket_info* force_send_socket, + union sockaddr_union* su, int proto, + enum ss_mismatch* mismatch); + + +inline static struct socket_info* get_send_socket(struct sip_msg* msg, + union sockaddr_union* su, int proto) +{ + return get_send_socket2(msg?msg->force_send_socket:0, su, proto, 0); +} +
-struct socket_info* get_send_socket(struct sip_msg* msg, - union sockaddr_union* su, int proto); struct socket_info* get_out_socket(union sockaddr_union* to, int proto); int check_self(str* host, unsigned short port, unsigned short proto); int check_self_port(unsigned short port, unsigned short proto);