Module: sip-router
Branch: master
Commit: 6335d07c4c77ed60fb8c2b5acc84d7c4b503221c
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6335d07c4c77ed60fb8c2b5acc84d7c4b503221c

Author: Daniel-Constantin Mierla <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
Date:   Wed Jul 17 12:22:31 2013 +0200

core: helper functions to lookup local socket from proto:host:port

---

 main.c        |    2 +-
 socket_info.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 socket_info.h |   10 ++++++
 3 files changed, 105 insertions(+), 1 deletions(-)

diff --git a/main.c b/main.c
index 05f45b5..24d3dc8 100644
--- a/main.c
+++ b/main.c
@@ -924,7 +924,7 @@ error:
 
 /* returns -1 on error, 0 on success
  * sets proto */
-static int parse_proto(unsigned char* s, long len, int* proto)
+int parse_proto(unsigned char* s, long len, int* proto)
 {
 #define PROTO2UINT3(a, b, c) ((        (((unsigned int)(a))<<16)+ \
                                                                (((unsigned 
int)(b))<<8)+  \
diff --git a/socket_info.c b/socket_info.c
index b489c8e..3314014 100644
--- a/socket_info.c
+++ b/socket_info.c
@@ -2057,3 +2057,97 @@ void init_proto_order()
 }
 
 
+/**
+ * parse '[port:]host[:port]' string to a broken down structure
+ */
+int parse_protohostport(str* ins, sr_phostp_t *r)
+{
+       char* first; /* first ':' occurrence */
+       char* second; /* second ':' occurrence */
+       char* p;
+       int bracket;
+       char* tmp;
+
+       first=second=0;
+       bracket=0;
+       memset(r, 0, sizeof(sr_phostp_t));
+
+       /* find the first 2 ':', ignoring possible ipv6 addresses
+        * (substrings between [])
+        */
+       for(p=ins->s; p<ins->s+ins->len; p++){
+               switch(*p){
+                       case '[':
+                               bracket++;
+                               if (bracket>1) goto error_brackets;
+                               break;
+                       case ']':
+                               bracket--;
+                               if (bracket<0) goto error_brackets;
+                               break;
+                       case ':':
+                               if (bracket==0){
+                                       if (first==0) first=p;
+                                       else if( second==0) second=p;
+                                       else goto error_colons;
+                               }
+                               break;
+               }
+       }
+       if (p==ins->s) return -1;
+       if (*(p-1)==':') goto error_colons;
+
+       if (first==0) { /* no ':' => only host */
+               r->host.s=ins->s;
+               r->host.len=(int)(p-ins->s);
+               goto end;
+       }
+       if (second) { /* 2 ':' found => check if valid */
+               if (parse_proto((unsigned char*)ins->s, first-ins->s, 
&r->proto)<0)
+                       goto error_proto;
+               r->port=strtol(second+1, &tmp, 10);
+               if ((tmp==0)||(*tmp)||(tmp==second+1)) goto error_port;
+               r->host.s=first+1;
+               r->host.len=(int)(second-r->host.s);
+               goto end;
+       }
+       /* only 1 ':' found => it's either proto:host or host:port */
+       r->port=strtol(first+1, &tmp, 10);
+       if ((tmp==0)||(*tmp)||(tmp==first+1)){
+               /* invalid port => it's proto:host */
+               if (parse_proto((unsigned char*)ins->s, first-ins->s, 
&r->proto)<0)
+                       goto error_proto;
+               r->host.s=first+1;
+               r->host.len=(int)(p-r->host.s);
+       }else{
+               /* valid port => its host:port */
+               r->host.s=ins->s;
+               r->host.len=(int)(first-r->host.s);
+       }
+end:
+       return 0;
+error_brackets:
+       LOG(L_ERR, "too many brackets in %.*s\n", ins->len, ins->s);
+       return -1;
+error_colons:
+       LOG(L_ERR, "too many colons in %.*s\n", ins->len, ins->s);
+       return -1;
+error_proto:
+       LOG(L_ERR, "bad protocol in %.*s\n", ins->len, ins->s);
+       return -1;
+error_port:
+       LOG(L_ERR, "bad port number in %.*s\n", ins->len, ins->s);
+       return -1;
+}
+
+/**
+ * lookup a local socket by '[port:]host[:port]' string
+ */
+struct socket_info* lookup_local_socket(str *phostp)
+{
+       sr_phostp_t r;
+       if(parse_protohostport(phostp, &r)<0)
+               return NULL;
+       return grep_sock_info(&r.host, (unsigned short)r.port,
+                       (unsigned short)r.proto);
+}
diff --git a/socket_info.h b/socket_info.h
index 926b317..ea0ab8b 100644
--- a/socket_info.h
+++ b/socket_info.h
@@ -105,6 +105,8 @@ struct socket_info** get_sock_info_list(unsigned short 
proto);
 int parse_phostport(char* s, char** host, int* hlen,
                                                                 int* port, 
int* proto);
 
+int parse_proto(unsigned char* s, long len, int* proto);
+
 char* get_valid_proto_name(unsigned short proto);
 
 /* helper function:
@@ -142,5 +144,13 @@ inline static struct socket_info* get_first_socket(void)
        return 0;
 }
 
+/* structure to break down 'proto:host:port' */
+typedef struct _sr_phostp {
+       int proto;
+       str host;
+       int port;
+} sr_phostp_t;
+
+struct socket_info* lookup_local_socket(str *phostp);
 
 #endif


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to