Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.462 diff -u -r1.462 chan_sip.c --- channels/chan_sip.c 27 Jul 2004 19:00:06 -0000 1.462 +++ channels/chan_sip.c 30 Jul 2004 20:01:13 -0000 @@ -5,7 +5,7 @@ * * Copyright (C) 1999, Mark Spencer * - * Mark Spencer + * Mark Spencer * * This program is free software, distributed under the terms of * the GNU General Public License @@ -301,15 +301,16 @@ char musicclass[MAX_LANGUAGE]; /* Music on Hold class */ char rdnis[256]; /* Referring DNIS */ char theirtag[256]; /* Their tag */ - char username[256]; - char peername[256]; + char username[256]; /* Username (from packet ) */ + char peername[256]; /* [name] in sip.conf */ char authname[256]; /* Who we use for authentication */ char uri[256]; /* Original requested URI */ - char peersecret[256]; - char peermd5secret[256]; + char fullcontact[AST_MAX_EXTENSION]; /* Contact URI from registration */ + char peersecret[256]; /* Config: Clear text secret /password */ + char peermd5secret[256]; /* Config: MD5 hash of secret */ char callerid[256]; /* Caller*ID */ int restrictcid; /* hide presentation from remote user */ - char via[256]; + char via[256]; /* Keep track of packet Via: headers */ char accountcode[20]; /* Account code */ char our_contact[256]; /* Our contact header */ char realm[256]; /* Authorization realm */ @@ -342,7 +343,7 @@ int dialogver; int promiscredir; /* Promiscuous redirection */ - int trustrpid; + int trustrpid; /* Do we support RPID headers? */ int progressinband; int dtmfmode; @@ -375,93 +376,98 @@ /* Structure for SIP user data. User's place calls to us */ struct sip_user { /* Users who can access various contexts */ - char name[80]; - char secret[80]; - char md5secret[80]; - char context[80]; - char callerid[80]; - char accountcode[20]; - char language[MAX_LANGUAGE]; + char name[80]; /* User [section] name in sip.conf */ + char secret[80]; /* Secret is the password in sip.conf */ + char md5secret[80]; /* MD5 hash instead of clear text password */ + char context[80]; /* Default context for dialplan */ + char callerid[80]; /* Caller id */ + char accountcode[20]; /* Account code for billing */ + char language[MAX_LANGUAGE]; /* Default language for this user */ char musicclass[MAX_LANGUAGE]; /* Music on Hold class */ + char fullcontact[80]; /* Full contact header */ char useragent[256]; /* User agent in SIP request */ - unsigned int callgroup; - unsigned int pickupgroup; - int nat; + unsigned int callgroup; /* Call groups, bitfield 0-31 */ + unsigned int pickupgroup; /* Pickup groups, bitfield 0-31 */ + int nat; /* NAT traversal support */ int hascallerid; - int amaflags; - int insecure; - int canreinvite; - int capability; + int amaflags; /* Default Ama flags for billing */ + int insecure; /* Don't bother with authentication */ + int canreinvite; /* Does this device support re-INVITE ? */ + int capability; /* Codec support (from sip.conf) */ #ifdef OSP_SUPPORT - int ospauth; /* Allow OSP Authentication */ + int ospauth; /* Allow OSP Authentication */ #endif - int dtmfmode; + int dtmfmode; /* DTMF we send *to* this user */ int inUse; - int incominglimit; + int incominglimit; /* Limit for calls to the PBX */ int outUse; - int outgoinglimit; - int promiscredir; + int outgoinglimit; /* Limit for calls from the PBX */ + int promiscredir; /* Support for 302 redirects */ int restrictcid; - int trustrpid; - int progressinband; - struct ast_ha *ha; + int trustrpid; /* Do we trust RPID headers ? */ + int progressinband; /* Inband notification of progress */ + struct ast_ha *ha; /* ACL from sip.conf */ #ifdef MYSQL_USERS int temponly; #endif /* MYSQL_FRIENDS */ - struct sip_user *next; + + struct sip_user *next; /* Next user in linked list */ }; /* Structure for SIP peer data, we place calls to peers if registred or fixed IP address (host) */ struct sip_peer { - char name[80]; - char secret[80]; - char md5secret[80]; + char name[80]; /* Peer name in [section] in sip.conf */ + char secret[80]; /* Peer secret (password) */ + char md5secret[80]; /* MD5 hash instead of cleartext password */ char context[80]; /* JK02: peers need context too to allow parking etc */ - char username[80]; - char tohost[80]; - char fromuser[80]; - char fromdomain[80]; - char mailbox[AST_MAX_EXTENSION]; - char language[MAX_LANGUAGE]; + char username[80]; /* Username to use when calling peer (until reg) */ + char tohost[80]; + char fromuser[80]; /* From: Username */ + char fromdomain[80]; /* From: domain */ + char mailbox[AST_MAX_EXTENSION];/* Voicemailbox to check for MWI */ + char language[MAX_LANGUAGE]; /* Default language for IVR prompts */ char musicclass[MAX_LANGUAGE]; /* Music on Hold class */ char useragent[256]; /* User agent in SIP request */ + char fullcontact[AST_MAX_EXTENSION]; /* Contact: header from registration */ int lastmsgssent; time_t lastmsgcheck; - int dynamic; - int expire; + int dynamic; /* Does this peer REGISTER to tell us where it is? */ + int expire; /* Expiration time */ int expiry; - int capability; - int rtptimeout; - int rtpholdtimeout; - int insecure; + int capability; /* Codec support */ + int rtptimeout; /* Timeout value for cancelling silent calls */ + int rtpholdtimeout; /* Timeout value for cancelling calls on hold */ + int insecure; /* Don't bother with auth */ #ifdef OSP_SUPPORT - int ospauth; /* Allow OSP Authentication */ + int ospauth; /* Allow OSP Authentication */ #endif - int nat; - int canreinvite; - unsigned int callgroup; - unsigned int pickupgroup; - int promiscredir; - int dtmfmode; - int trustrpid; - int progressinband; - struct sockaddr_in addr; + int nat; /* NAT traversal including symmetric RTP */ + int canreinvite; /* Does this device support RE-INVITE ? */ + unsigned int callgroup; /* Call groups this peer belong to 0-31 bitfield*/ + unsigned int pickupgroup; /* Pickup groups 0-31 0-31 bitfield*/ + int promiscredir; /* Do we accept 302 redirects? */ + int dtmfmode; /* DTMF type we send *to* this peer */ + int trustrpid; /* Trust RPID headers from this peer */ + int progressinband; /* Inband notification support */ + struct sockaddr_in addr; /* IP address and port */ struct in_addr mask; /* Qualification */ struct sip_pvt *call; /* Call pointer */ - int pokeexpire; /* When to expire poke */ - int lastms; /* How long last response took (in ms), or -1 for no response */ - int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ - struct timeval ps; /* Ping send time */ - - struct sockaddr_in defaddr; - struct ast_ha *ha; - int delme; + int pokeexpire; /* When to expire poke */ + int lastms; /* How long last response took (in ms), or -1 for no response */ + int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ + struct timeval ps; /* NAT Ping send time */ + + struct sockaddr_in defaddr; /* Default IP address (used until REGISTER) */ + struct ast_ha *ha; /* ACL: from sip.conf */ + + int delme; /* Flags for database and autocreate peers that we delete */ int selfdestruct; int lastmsg; int temponly; - struct sip_peer *next; + + struct sip_peer *next; /* Next peer in linked list */ }; AST_MUTEX_DEFINE_STATIC(sip_reload_lock); @@ -1275,6 +1281,7 @@ strncpy(r->peermd5secret, p->md5secret, sizeof(r->peermd5secret)-1); strncpy(r->username, p->username, sizeof(r->username)-1); strncpy(r->tohost, p->tohost, sizeof(r->tohost)-1); + strncpy(r->fullcontact, p->fullcontact, sizeof(r->fullcontact)-1); if (ast_strlen_zero(r->tohost)) { if (p->addr.sin_addr.s_addr) ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->addr.sin_addr); @@ -3656,7 +3663,21 @@ } else { snprintf(invite, sizeof(invite), "sip:%s", p->tohost); } - strncpy(p->uri, invite, sizeof(p->uri) - 1); + + /* This is a patch, trying to use the full contact header from registration if + we have it. After a restart, we might have lost it and have to fix something + while waiting for a new registration */ + if (!ast_strlen_zero(p->fullcontact)) { /* If we have a full contact header, use it */ + strncpy(p->uri, p->fullcontact, sizeof(p->uri) - 1); /* Copy original contact header */ + strncpy(invite, p->fullcontact, sizeof(invite)-1); /* Copy original contact header */ + if (sipdebug) + ast_log(LOG_DEBUG, ": Full contact=%s used in uri, invite/to string :%s: \n", p->fullcontact,invite); + } else { + strncpy(p->uri, invite, sizeof(p->uri) - 1); + if (sipdebug) + ast_log(LOG_DEBUG, ": Old style contact used in uri, invite/to string :%s: \n", invite); + } + /* If there is a VXML URL append it to the SIP URL */ if (vxml_url) { @@ -3697,6 +3718,7 @@ snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); else /* Work around buggy UNIDEN UIP200 firmware */ snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); + initreqprep(&req, p, cmd, vxml_url); } else reqprep(&req, p, cmd, 0, 1); @@ -4237,6 +4259,10 @@ if (n) *n = '\0'; } + /* Save the verbatim contact header for following invites */ + strncpy(p->fullcontact, c, sizeof(p->fullcontact)-1); + + /* If expires=0, unregister peer */ if (!strcasecmp(c, "*") || !expiry) { /* This means remove all registrations and return OK */ memset(&p->addr, 0, sizeof(p->addr)); @@ -5206,6 +5232,7 @@ strncpy(p->accountcode, user->accountcode, sizeof(p->accountcode) -1); strncpy(p->language, user->language, sizeof(p->language) -1); strncpy(p->musicclass, user->musicclass, sizeof(p->musicclass) -1); + strncpy(p->fullcontact, user->fullcontact, sizeof(p->fullcontact) -1); p->canreinvite = user->canreinvite; p->amaflags = user->amaflags; p->callgroup = user->callgroup; @@ -5290,6 +5317,7 @@ strncpy(p->context, peer->context, sizeof(p->context) - 1); strncpy(p->peersecret, peer->secret, sizeof(p->peersecret) - 1); strncpy(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret) - 1); + strncpy(p->fullcontact, peer->fullcontact, sizeof(p->fullcontact) - 1); p->callgroup = peer->callgroup; p->pickupgroup = peer->pickupgroup; p->capability = peer->capability; @@ -5582,6 +5610,7 @@ ast_cli(fd, " ToHost : %s\n", peer->tohost); ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); + ast_cli(fd, " Username : %s\n", peer->username); ast_cli(fd, " Codecs : "); /* This should really be a function in frame.c */ if (peer->capability & AST_FORMAT_G723_1) @@ -5626,6 +5655,9 @@ strncpy(status, "UNKNOWN", sizeof(status) - 1); ast_cli(fd, "%s\n",status); ast_cli(fd, " Useragent : %s\n", peer->useragent); + if (!ast_strlen_zero(peer->fullcontact)) + ast_cli(fd, " Contact: : %s\n", peer->fullcontact); + ast_cli(fd,"\n"); } else { ast_cli(fd,"Peer %s not found.\n", argv[3]); @@ -5790,6 +5822,8 @@ if (cur->dtmfmode & SIP_DTMF_INBAND) strncat(tmp, "inband ", sizeof(tmp) - strlen(tmp) - 1); ast_cli(fd, " DTMF Mode: %s\n\n", tmp); + if (!ast_strlen_zero(cur->fullcontact)) + ast_cli(fd, " Contact: : %s\n", cur->fullcontact); found++; } cur = cur->next; @@ -7852,6 +7886,7 @@ strncpy(user->context, default_context, sizeof(user->context)-1); strncpy(user->language, default_language, sizeof(user->language)-1); strncpy(user->musicclass, global_musicclass, sizeof(user->musicclass)-1); + strcpy(user->fullcontact, ""); while(v) { if (!strcasecmp(v->name, "context")) { strncpy(user->context, v->value, sizeof(user->context) - 1); @@ -7968,6 +8003,7 @@ strncpy(peer->context, default_context, sizeof(peer->context)-1); strncpy(peer->language, default_language, sizeof(peer->language)-1); strncpy(peer->musicclass, global_musicclass, sizeof(peer->musicclass)-1); + strcpy(peer->fullcontact, ""); peer->addr.sin_port = htons(DEFAULT_SIP_PORT); peer->addr.sin_family = AF_INET; peer->expiry = expiry; @@ -8029,6 +8065,7 @@ if (peer) { if (!found) { strncpy(peer->name, name, sizeof(peer->name)-1); + strcpy(peer->fullcontact, ""); strncpy(peer->context, default_context, sizeof(peer->context)-1); strncpy(peer->language, default_language, sizeof(peer->language)-1); strncpy(peer->musicclass, global_musicclass, sizeof(peer->musicclass)-1);