diff -r -U4 asterisk-1.2.9.1/channels/chan_sip.c asterisk-1.2.9.1+byte/channels/chan_sip.c --- asterisk-1.2.9.1/channels/chan_sip.c 2006-05-25 18:18:01.000000000 +0100 +++ asterisk-1.2.9.1+byte/channels/chan_sip.c 2006-07-24 10:11:26.295076678 +0100 @@ -124,9 +124,9 @@ #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 */ @@ -4815,8 +4815,10 @@ 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; @@ -4875,12 +4877,41 @@ 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 */ @@ -4932,9 +4963,9 @@ } 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); @@ -11732,30 +11763,48 @@ 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))