diff -r -U10 asterisk-1.2.1/channels/chan_sip.c asterisk-1.2.1+byte/channels/chan_sip.c --- asterisk-1.2.1/channels/chan_sip.c 2005-12-05 00:01:17.000000000 +0000 +++ asterisk-1.2.1+byte/channels/chan_sip.c 2005-12-19 14:53:31.000000000 +0000 @@ -116,21 +116,21 @@ below EXPIRY_GUARD_LIMIT */ static int max_expiry = DEFAULT_MAX_EXPIRY; static int default_expiry = DEFAULT_DEFAULT_EXPIRY; #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #define CALLERID_UNKNOWN "Unknown" - +#define MAX_CIDNUM_LEN 79 /* It's used in the Contact header too so it must fit. */ #define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */ #define DEFAULT_FREQ_OK 60 * 1000 /* How often to check for the host to be up */ #define DEFAULT_FREQ_NOTOK 10 * 1000 /* How often to check, if the host is down... */ #define DEFAULT_RETRANS 1000 /* How frequently to retransmit */ /* 2 * 500 ms in RFC 3261 */ #define MAX_RETRANS 6 /* Try only 6 times for retransmissions, a total of 7 transmissions */ #define MAX_AUTHTRIES 3 /* Try authentication three times, then fail */ @@ -4709,20 +4709,22 @@ char *invite = invite_buf; size_t invite_max = sizeof(invite_buf); char from[256]; char to[256]; char tmp[BUFSIZ/2]; char tmp2[BUFSIZ/2]; char iabuf[INET_ADDRSTRLEN]; char *l = NULL, *n = NULL; int x; char urioptions[256]=""; + char cidnum[MAX_CIDNUM_LEN+1]; + int pos=0; if (ast_test_flag(p, SIP_USEREQPHONE)) { char onlydigits = 1; x=0; /* Test p->username against allowed characters in AST_DIGIT_ANY If it matches the allowed characters list, then sipuser = ";user=phone" If not, then sipuser = "" */ /* + is allowed in first position in a tel: uri */ @@ -4769,24 +4771,53 @@ else /* Save for any further attempts */ ast_copy_string(p->fromname, n, sizeof(p->fromname)); if (pedanticsipchecking) { ast_uri_encode(n, tmp, sizeof(tmp), 0); n = tmp; ast_uri_encode(l, tmp2, sizeof(tmp2), 0); l = tmp2; } - if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ - snprintf(from, sizeof(from), "\"%s\" ;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag); + if (!ast_isphonenumber(l)) { + static char hex[] = "0123456789ABCDEF"; + int i; + for (i=0; i= 65 && l[i] <= 90) //A-Z + || (l[i] >= 97 && l[i] <= 122) //a-z + || (l[i] >= 48 && l[i] <= 57) //0-9 + || (l[i] == 35) //# + || (l[i] == 42) //* + || (l[i] == 43) //+ + || (l[i] == 45) //- + || (l[i] == 95) //_ + ) { // valid char + cidnum[pos]=l[i]; + pos++; + if (pos == MAX_CIDNUM_LEN) break; + } else { // invalid char + if (pos+3 > MAX_CIDNUM_LEN) break; + cidnum[pos] = '%'; + cidnum[pos+1] = hex[l[i] >> 4]; + cidnum[pos+2] = hex[l[i] & 0x0f]; + pos+=3; + if (pos == MAX_CIDNUM_LEN) break; + } + } + cidnum[pos]='\0'; + } + + if ((ourport != 5060) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */ + snprintf(from, sizeof(from), "\"%s\" ;tag=%s", n, (pos == 0 ? l : cidnum), ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, ourport, p->tag); else - snprintf(from, sizeof(from), "\"%s\" ;tag=%s", n, l, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag); + snprintf(from, sizeof(from), "\"%s\" ;tag=%s", n, (pos == 0 ? l : cidnum), ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain, p->tag); /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ if (!ast_strlen_zero(p->fullcontact)) { /* If we have full contact, trust it */ ast_build_string(&invite, &invite_max, "%s", p->fullcontact); } else { /* Otherwise, use the username while waiting for registration */ ast_build_string(&invite, &invite_max, "sip:"); if (!ast_strlen_zero(p->username)) { n = p->username; @@ -4822,21 +4853,21 @@ /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. * OTOH, then we won't have anything in p->route anyway */ /* Build Remote Party-ID and From */ if (ast_test_flag(p, SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { build_rpid(p); add_header(req, "From", p->rpid_from); } else { add_header(req, "From", from); } add_header(req, "To", to); - ast_copy_string(p->exten, l, sizeof(p->exten)); + ast_copy_string(p->exten, (pos == 0 ? l : cidnum), sizeof(p->exten)); build_contact(p); add_header(req, "Contact", p->our_contact); add_header(req, "Call-ID", p->callid); add_header(req, "CSeq", tmp); add_header(req, "User-Agent", default_useragent); add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); if (p->rpid) add_header(req, "Remote-Party-ID", p->rpid); } @@ -11467,62 +11498,81 @@ /*! \brief sip_request: PBX interface function -build SIP pvt structure ---*/ /* SIP calls initiated by the PBX arrive here */ static struct ast_channel *sip_request_call(const char *type, int format, void *data, int *cause) { int oldformat; struct sip_pvt *p; struct ast_channel *tmpc = NULL; char *ext, *host; char tmp[256]; char *dest = data; + char *fakehost = NULL; oldformat = format; format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); if (!format) { ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(global_capability)); return NULL; } p = sip_alloc(NULL, NULL, 0, SIP_INVITE); if (!p) { ast_log(LOG_WARNING, "Unable to build sip pvt data for '%s'\n", (char *)data); return NULL; } p->options = calloc(1, sizeof(*p->options)); if (!p->options) { ast_log(LOG_ERROR, "Out of memory\n"); return NULL; } ast_copy_string(tmp, dest, sizeof(tmp)); - host = strchr(tmp, '@'); - if (host) { - *host = '\0'; - host++; - ext = tmp; - } else { - ext = strchr(tmp, '/'); - if (ext) { - *ext++ = '\0'; - host = tmp; + ext = strchr(tmp, '!'); + if (ext) { + *ext = '\0'; + ext++; + fakehost = tmp; + host = strchr(ext, '@'); + if (host) { + *host++ = '\0'; } else { - host = tmp; + host = ext; ext = NULL; } + } else { + host = strchr(tmp, '@'); + if (host) { + *host = '\0'; + host++; + ext = tmp; + } else { + ext = strchr(tmp, '/'); + if (ext) { + *ext++ = '\0'; + host = tmp; + } + else { + host = tmp; + ext = NULL; + } + } } - if (create_addr(p, host)) { + if (create_addr(p, (fakehost ? fakehost : host))) { *cause = AST_CAUSE_UNREGISTERED; sip_destroy(p); return NULL; } + if (fakehost) + ast_copy_string(p->tohost, host, sizeof(p->tohost)); + if (ast_strlen_zero(p->peername) && ext) ast_copy_string(p->peername, ext, sizeof(p->peername)); /* Recalculate our side, and recalculate Call ID */ if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); build_via(p, p->via, sizeof(p->via)); build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain); /* We have an extension to call, don't use the full contact here */ /* This to enable dialling registered peers with extension dialling,