another batch of minor code simplifications
authorLuigi Rizzo <rizzo@icir.org>
Mon, 10 Apr 2006 09:53:22 +0000 (09:53 +0000)
committerLuigi Rizzo <rizzo@icir.org>
Mon, 10 Apr 2006 09:53:22 +0000 (09:53 +0000)
(moving repeated expressions into a function, const on
some arguments)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@18784 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index 1b7ce5f..66d3e18 100644 (file)
@@ -101,7 +101,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #define TRUE 1
 #endif
 
 #define VIDEO_CODEC_MASK       0x1fc0000 /*!< Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO */
 #ifndef IPTOS_MINCOST
 #define IPTOS_MINCOST          0x02
@@ -322,7 +321,7 @@ static const struct cfsip_options {
        int id;                 /*!< Bitmap ID */
        int supported;          /*!< Supported by Asterisk ? */
        char * const text;      /*!< Text id, as in standard */
-} sip_options[] = {
+} sip_options[] = {    /* XXX used in 3 places */
        /* Replaces: header for transfer */
        { SIP_OPT_REPLACES,     SUPPORTED,      "replaces" },   
        /* RFC3262: PRACK 100% reliability */
@@ -788,6 +787,7 @@ struct sip_user {
 };
 
 /*! \brief Structure for SIP peer data, we place calls to peers if registered  or fixed IP address (host) */
+/* XXX field 'name' must be first otherwise sip_addrcmp() will fail */
 struct sip_peer {
        ASTOBJ_COMPONENTS(struct sip_peer);     /*!< name, refcount, objflags,  object pointers */
                                        /*!< peer->name is the unique name of this object */
@@ -966,8 +966,8 @@ static void sip_dump_history(struct sip_pvt *dialog);       /* Dump history to LOG_DEB
 static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
 static int transmit_state_notify(struct sip_pvt *p, int state, int full);
 static char *gettag(struct sip_request *req, char *header, char *tagbuf, int tagbufsize);
-static int find_sip_method(char *msg);
-static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
+static int find_sip_method(const char *msg);
+static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported);
 static void sip_destroy(struct sip_pvt *p);
 static void sip_destroy_peer(struct sip_peer *peer);
 static void sip_destroy_user(struct sip_user *user);
@@ -1023,25 +1023,36 @@ static struct ast_rtp_protocol sip_rtp = {
 };
 
 
-/*! \brief Find SIP method from header
- * Strictly speaking, SIP methods are case SENSITIVE, but we don't check 
- * following Jon Postel's rule: Be gentle in what you accept, strict with what you send */
-static int find_sip_method(char *msg)
+/*! \brief returns true if 'name' (with optional trailing whitespace)
+ * matches the sip method 'id'.
+ * Strictly speaking, SIP methods are case SENSITIVE, but we do
+ * a case-insensitive comparison to be more tolerant.
+ */
+static int method_match(enum sipmethod id, const char *name)
+{
+       int len = strlen(sip_methods[id].text);
+       int l_name = name ? strlen(name) : 0;
+       /* true if the string is long enough, and ends with whitespace, and matches */
+       return (l_name >= len && name[len] < 33 &&
+               !strncasecmp(sip_methods[id].text, name, len));
+}
+
+/*! \brief  find_sip_method: Find SIP method from header */
+static int find_sip_method(const char *msg)
 {
        int i, res = 0;
        
        if (ast_strlen_zero(msg))
                return 0;
-
        for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
-               if (!strcasecmp(sip_methods[i].text, msg)) 
+               if (method_match(i, msg))
                        res = sip_methods[i].id;
        }
        return res;
 }
 
 /*! \brief Parse supported header in incoming packet */
-static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported)
+static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported)
 {
        char *next, *sep;
        char *temp = ast_strdupa(supported);
@@ -1092,29 +1103,35 @@ static inline int sip_debug_test_addr(const struct sockaddr_in *addr)
        return 1;
 }
 
+/* The real destination address for a write */
+static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p)
+{
+       return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
+}
+
+static const char *sip_nat_mode(const struct sip_pvt *p)
+{
+       return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
+}
+
 /*! \brief Test PVT for debugging output */
 static inline int sip_debug_test_pvt(struct sip_pvt *p) 
 {
        if (!sipdebug)
                return 0;
-       return sip_debug_test_addr(ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ? &p->recv : &p->sa);
+       return sip_debug_test_addr(sip_real_dst(p));
 }
 
-
 /*! \brief Transmit SIP message */
 static int __sip_xmit(struct sip_pvt *p, char *data, int len)
 {
        int res;
        char iabuf[INET_ADDRSTRLEN];
+       const struct sockaddr_in *dst = sip_real_dst(p);
+       res=sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
 
-       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
-               res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in));
-       else
-               res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in));
-
-       if (res != len) {
-               ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), res, strerror(errno));
-       }
+       if (res != len)
+               ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(iabuf, sizeof(iabuf), dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
        return res;
 }
 
@@ -6843,17 +6860,14 @@ static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
        if (!req)
                req = &p->initreq;
        ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
-       
        c = get_in_brackets(tmp);
        if (strncmp(c, "sip:", 4)) {
                ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
                return -1;
        }
        c += 4;
-       if ((a = strchr(c, '@')))
-               *a = '\0';
-       if ((a = strchr(c, ';'))) 
-               *a = '\0';
+       a = c;
+       strsep(&a, "@;");       /* trim anything after @ or ; */
        
        if (sip_debug_test_pvt(p))
                ast_verbose("Looking for %s in %s\n", c, p->context);
@@ -6916,8 +6930,8 @@ static int check_via(struct sip_pvt *p, struct sip_request *req)
                p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT);
 
                if (sip_debug_test_pvt(p)) {
-                       c = (ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE) ? "NAT" : "non-NAT";
-                       ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port), c);
+                       const struct sockaddr_in *dst = sip_real_dst(p);
+                       ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
                }
        }
        return 0;