From ccca5843fde0d2b27fb2da684e87786cdee6af4c Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Fri, 6 Oct 2006 15:41:12 +0000 Subject: [PATCH] Two things: 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 | 65 ++++++++++++++++++++++++----------------- configs/sip.conf.sample | 9 ++++++ 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2aa8ee3634..2c7007c63b 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -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(®l, 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(®_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; } diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index 52cb6cbb80..319d53e1a1 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -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 ;