Two things:
authorLuigi Rizzo <rizzo@icir.org>
Fri, 6 Oct 2006 15:41:12 +0000 (15:41 +0000)
committerLuigi Rizzo <rizzo@icir.org>
Fri, 6 Oct 2006 15:41:12 +0000 (15:41 +0000)
1. slightly rearrange/simplify the parsing of the argument in sip_register.
   This brings in a patch that has been in Mantis (5834)  for ages,
   and is the larger part of the commit;

2. implement the "contact" option for peers, similar to the one in users.conf:

   If you put a "contact" option with a non-empty argument (e.g. contact=123)
   in a peer section, asterisk will register with the provider as if you had a

        register= username:secret@host/contact

   line in the general section.

The latter is a very small is a new feature so i am not putting it
in the 1.4 branch, although the "contact" option in user.conf is
already in the 1.4 branch and so it wouldn't be too strange to
merge it.

Note that the implementation of "contact" is much simpler than
the one in 5834, and limited to a few lines in build_peer().

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

channels/chan_sip.c
configs/sip.conf.sample

index 2aa8ee3..2c7007c 100644 (file)
@@ -4243,44 +4243,45 @@ static struct sip_pvt *find_call(struct sip_request *req, struct sockaddr_in *si
 static int sip_register(char *value, int lineno)
 {
        struct sip_registry *reg;
-       char copy[256];
-       char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
+       int portnum = 0;
+       char username[256] = "";
+       char *hostname=NULL, *secret=NULL, *authuser=NULL;
        char *porta=NULL;
        char *contact=NULL;
-       char *stringp=NULL;
-       
+
        if (!value)
                return -1;
-       ast_copy_string(copy, value, sizeof(copy));
-       stringp=copy;
-       username = stringp;
-       hostname = strrchr(stringp, '@');
+       ast_copy_string(username, value, sizeof(username));
+       /* First split around the last '@' then parse the two components. */
+       hostname = strrchr(username, '@'); /* allow @ in the first part */
        if (hostname)
                *hostname++ = '\0';
        if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
                ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
                return -1;
        }
-       stringp = username;
-       username = strsep(&stringp, ":");
-       if (username) {
-               secret = strsep(&stringp, ":");
-               if (secret) 
-                       authuser = strsep(&stringp, ":");
+       /* split user[:secret[:authuser]] */
+       secret = strchr(username, ':');
+       if (secret) {
+               *secret++ = '\0';
+               authuser = strchr(secret, ':');
+               if (authuser)
+                       *authuser++ = '\0';
        }
-       stringp = hostname;
-       hostname = strsep(&stringp, "/");
-       if (hostname) 
-               contact = strsep(&stringp, "/");
+       /* split host[:port][/contact] */
+       contact = strchr(hostname, '/');
+       if (contact)
+               *contact++ = '\0';
        if (ast_strlen_zero(contact))
                contact = "s";
-       stringp=hostname;
-       hostname = strsep(&stringp, ":");
-       porta = strsep(&stringp, ":");
-       
-       if (porta && !atoi(porta)) {
-               ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
-               return -1;
+       porta = strchr(hostname, ':');
+       if (porta) {
+               *porta++ = '\0';
+               portnum = atoi(porta);
+               if (portnum == 0) {
+                       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
+                       return -1;
+               }
        }
        if (!(reg = ast_calloc(1, sizeof(*reg)))) {
                ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
@@ -4307,7 +4308,7 @@ static int sip_register(char *value, int lineno)
        reg->expire = -1;
        reg->timeout =  -1;
        reg->refresh = default_expiry;
-       reg->portno = porta ? atoi(porta) : 0;
+       reg->portno = portnum;
        reg->callid_valid = FALSE;
        reg->ocseq = INITIAL_CSEQ;
        ASTOBJ_CONTAINER_LINK(&regl, reg);      /* Add the new registry entry to the list */
@@ -15368,6 +15369,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
        struct ast_variable *tmpvar = NULL;
        struct ast_flags peerflags[2] = {{(0)}};
        struct ast_flags mask[2] = {{(0)}};
+       char contact[256] = "";
 
 
        if (!realtime)
@@ -15503,6 +15505,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
                        ast_copy_string(peer->language, v->value, sizeof(peer->language));
                } else if (!strcasecmp(v->name, "regexten")) {
                        ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
+               } else if (!strcasecmp(v->name, "contact")) {
+                       ast_copy_string(contact, v->value, sizeof(contact));
                } else if (!strcasecmp(v->name, "call-limit")) {
                        peer->call_limit = atoi(v->value);
                        if (peer->call_limit < 0)
@@ -15612,6 +15616,15 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
                reg_source_db(peer);
        ASTOBJ_UNMARK(peer);
        ast_free_ha(oldha);
+       if (!ast_strlen_zero(contact)) { /* build string from peer info */
+               char *reg_string;
+
+               asprintf(&reg_string, "%s:%s@%s/%s", peer->username, peer->secret, peer->tohost, contact);
+               if (reg_string) {
+                       sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
+                       free(reg_string);
+               }
+       }
        return peer;
 }
 
index 52cb6cb..319d53e 100644 (file)
@@ -432,6 +432,7 @@ srvlookup=yes                       ; Enable DNS SRV lookups on outbound calls
 ;                             sendrpid
 ;                             outboundproxy
 ;                             rfc2833compensate
+;                             contact
 
 ;[sip_proxy]
 ; For incoming calls only. Example: FWD (Free World Dialup)
@@ -454,6 +455,14 @@ srvlookup=yes                      ; Enable DNS SRV lookups on outbound calls
                                ; Call-limits will not be enforced on real-time peers,
                                ; since they are not stored in-memory
 
+;--- sample definition for a provider
+;[provider1]
+;type=peer
+;host=sip.provider1.com
+;username=4015552299           ; how your provider knows you
+;secret=youwillneverguessit
+;contact=123                   ; tell asterisk to register as username:secret@host/contact
+
 ;------------------------------------------------------------------------------
 ; Definitions of locally connected SIP devices
 ;