--- channels/chan_sip.c.org Thu Dec 18 22:08:05 2003 +++ channels/chan_sip.c Thu Dec 18 22:46:00 2003 @@ -89,6 +89,7 @@ #define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER" + static char context[AST_MAX_EXTENSION] = "default"; static char language[MAX_LANGUAGE] = ""; @@ -132,6 +133,9 @@ static int ourport; static int sipdebug = 0; +static int sipdebugfilter = 0; +static char sipdebugfilter_ip[AST_MAX_EXTENSION]; +static int sipdebugfilter_port = 5060; static int tos = 0; @@ -180,58 +184,59 @@ static struct sip_pvt { ast_mutex_t lock; /* Channel private lock */ - char callid[80]; /* Global CallID */ - char randdata[80]; /* Random data */ - unsigned int ocseq; /* Current outgoing seqno */ - unsigned int icseq; /* Current incoming seqno */ + char callid[80]; /* Global CallID */ + char randdata[80]; /* Random data */ + unsigned int ocseq; /* Current outgoing seqno */ + unsigned int icseq; /* Current incoming seqno */ unsigned int callgroup; unsigned int pickupgroup; - int lastinvite; /* Last Cseq of invite */ - int alreadygone; /* Whether or not we've already been destroyed by or peer */ - int needdestroy; /* if we need to be destroyed */ - int capability; /* Special capability */ + int lastinvite; /* Last Cseq of invite */ + int alreadygone; /* Whether or not we've already been destroyed by or peer */ + int needdestroy; /* if we need to be destroyed */ + int capability; /* Special capability */ int jointcapability; /* Supported capability at both ends */ int noncodeccapability; - int outgoing; /* Outgoing or incoming call? */ - int authtries; /* Times we've tried to authenticate */ - int insecure; /* Don't check source port/ip */ - int expiry; /* How long we take to expire */ - int branch; /* One random number */ - int canreinvite; /* Do we support reinvite */ - int ringing; /* Have sent 180 ringing */ - int progress; /* Have sent 183 message progress */ - int tag; /* Another random number */ - int nat; /* Whether to try to support NAT */ - int sessionid; /* SDP Session ID */ - int sessionversion; /* SDP Session Version */ + int outgoing; /* Outgoing or incoming call? */ + int authtries; /* Times we've tried to authenticate */ + int insecure; /* Don't check source port/ip */ + int expiry; /* How long we take to expire */ + int branch; /* One random number */ + int canreinvite; /* Do we support reinvite */ + int ringing; /* Have sent 180 ringing */ + int progress; /* Have sent 183 message progress */ + int tag; /* Another random number */ + int nat; /* Whether to try to support NAT */ + int sessionid; /* SDP Session ID */ + int sessionversion; /* SDP Session Version */ struct sockaddr_in sa; /* Our peer */ struct sockaddr_in redirip; /* Where our RTP should be going if not to us */ - struct sockaddr_in vredirip; /* Where our Video RTP should be going if not to us */ + struct sockaddr_in vredirip; /* Where our Video RTP should be going if not to us */ struct sockaddr_in recv; /* Received as */ struct in_addr ourip; /* Our IP */ struct ast_channel *owner; /* Who owns us */ - char exten[AST_MAX_EXTENSION]; /* Extention where to start */ - char refer_to[AST_MAX_EXTENSION]; /* Place to store REFER-TO extension */ - char referred_by[AST_MAX_EXTENSION];/* Place to store REFERRED-BY extension */ - char refer_contact[AST_MAX_EXTENSION];/* Place to store Contact info from a REFER extension */ + char exten[AST_MAX_EXTENSION]; /* Extention where to start */ + char refer_to[AST_MAX_EXTENSION]; /* Place to store REFER-TO extension */ + char referred_by[AST_MAX_EXTENSION]; /* Place to store REFERRED-BY extension */ + char refer_contact[AST_MAX_EXTENSION]; /* Place to store Contact info from a REFER extension */ struct sip_pvt *refer_call; /* Call we are referring */ struct sip_route *route; /* Head of linked list of routing steps (fm Record-Route) */ char remote_party_id[256]; char from[256]; - char context[AST_MAX_EXTENSION]; - char fromdomain[AST_MAX_EXTENSION]; /* Domain to show in the from field */ - char fromuser[AST_MAX_EXTENSION]; /* Domain to show in the user field */ - char tohost[AST_MAX_EXTENSION]; /* Host we should put in the "to" field */ - char language[MAX_LANGUAGE]; + char useragent[AST_MAX_EXTENSION]; /* User agent in SIP request */ + char context[AST_MAX_EXTENSION]; /* Config: context to use */ + char fromdomain[AST_MAX_EXTENSION]; /* Config: Domain to show in the from field */ + char fromuser[AST_MAX_EXTENSION]; /* Config: Domain to show in the user field */ + char tohost[AST_MAX_EXTENSION]; /* Host we should put in the "to" field */ + char language[MAX_LANGUAGE]; /* Config: Language setting */ char rdnis[256]; /* Referring DNIS */ char theirtag[256]; /* Their tag */ char username[256]; char peername[256]; char uri[256]; /* Original requested URI */ - char peersecret[256]; - char peermd5secret[256]; - char callerid[256]; /* Caller*ID */ - int restrictcid; /* hide presentation from remote user */ + char peersecret[256]; /* Config: Secret cleartext */ + char peermd5secret[256]; /* Config: Secret in MD5 hash */ + char callerid[256]; /* Caller*ID */ + int restrictcid; /* hide presentation from remote user */ char via[256]; char accountcode[20]; /* Account code */ char our_contact[256]; /* Our contact header */ @@ -239,15 +244,15 @@ char nonce[256]; /* Authorization nonce */ char domain[256]; /* Authorization nonce */ char lastmsg[256]; /* Last Message sent/received */ - int amaflags; /* AMA Flags */ - int pendinginvite; /* Any pending invite */ - int pendingbye; /* Need to send bye after we ack? */ - int gotrefer; /* Got a refer? */ + int amaflags; /* AMA Flags */ + int pendinginvite; /* Any pending invite */ + int pendingbye; /* Need to send bye after we ack? */ + int gotrefer; /* Got a refer? */ struct sip_request initreq; /* Initial request */ - int maxtime; /* Max time for first response */ - int initid; /* Auto-congest ID if appropriate */ - int autokillid; /* Auto-kill ID */ + int maxtime; /* Max time for first response */ + int initid; /* Auto-congest ID if appropriate */ + int autokillid; /* Auto-kill ID */ int subscribed; int stateid; @@ -331,10 +336,10 @@ /* 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 */ + 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; @@ -355,33 +360,33 @@ } peerl = { NULL, AST_MUTEX_INITIALIZER }; -#define REG_STATE_UNREGISTERED 0 +#define REG_STATE_UNREGISTERED 0 #define REG_STATE_REGSENT 1 #define REG_STATE_AUTHSENT 2 -#define REG_STATE_REGISTERED 3 +#define REG_STATE_REGISTERED 3 #define REG_STATE_REJECTED 4 #define REG_STATE_TIMEOUT 5 #define REG_STATE_NOAUTH 6 struct sip_registry { - ast_mutex_t lock; /* Channel private lock */ - struct sockaddr_in addr; /* Who we connect to for registration purposes */ - char username[80]; /* Who we are registering as */ - char authuser[80]; /* Who we *authenticate* as */ + ast_mutex_t lock; /* Channel private lock */ + struct sockaddr_in addr; /* Who we connect to for registration purposes */ + char username[80]; /* Who we are registering as */ + char authuser[80]; /* Who we *authenticate* as */ char hostname[80]; - char secret[80]; /* Password or key name in []'s */ + char secret[80]; /* Password or key name in []'s */ char md5secret[80]; - char contact[80]; /* Contact extension */ + char contact[80]; /* Contact extension */ char random[80]; - int expire; /* Sched ID of expiration */ - int timeout; /* sched id of sip_reg_timeout */ - int refresh; /* How often to refresh */ - struct sip_pvt *call; /* create a sip_pvt structure for each outbound "registration call" in progress */ + int expire; /* Sched ID of expiration */ + int timeout; /* sched id of sip_reg_timeout */ + int refresh; /* How often to refresh */ + struct sip_pvt *call; /* create a sip_pvt structure for each outbound "registration call" in progress */ int regstate; int callid_valid; /* 0 means we haven't chosen callid for this registry yet. */ char callid[80]; /* Global CallID for this registry */ unsigned int ocseq; /* Sequence number we got to for REGISTERs for this registry */ - struct sockaddr_in us; /* Who the server thinks we are */ + struct sockaddr_in us; /* Who the server thinks we are */ struct sip_registry *next; }; @@ -445,6 +450,7 @@ return 0; } +/* Retransmit SIP message if no answer */ static int retrans_pkt(void *data) { struct sip_pkt *pkt=data; @@ -454,9 +460,9 @@ pkt->retrans++; if (sipdebug) { if (pkt->owner->nat) - ast_verbose("Retransmitting #%d (NAT):\n%s\n to %s:%d\n", pkt->retrans, pkt->data, inet_ntoa(pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port)); + ast_verbose("----\n* Retransmitting #%d (NAT) to %s:%d\n%s\n---\n", pkt->retrans, inet_ntoa(pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port),pkt->data); else - ast_verbose("Retransmitting #%d (no NAT):\n%s\n to %s:%d\n", pkt->retrans, pkt->data, inet_ntoa(pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port)); + ast_verbose("---\n* Retransmitting #%d (no NAT) to %s:%d\n%s\n---\n", pkt->retrans, inet_ntoa(pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port),pkt->data); } __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); res = 1; @@ -592,10 +598,17 @@ { int res; if (sipdebug) { + if (!sipdebugfilter || ( !strcmp(sipdebugfilter_ip, inet_ntoa(p->recv.sin_addr)) && (int) ntohs(p->recv.sin_port) == sipdebugfilter_port )) { if (p->nat) - ast_verbose("%sTransmitting (NAT):\n%s\n to %s:%d\n", reliable ? "Reliably " : "", req->data, inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); + ast_verbose("--- %s Transmitting (NAT) to %s:%d\n%s\n---\n", reliable ? "Reliably " : "", inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port),req->data); else - ast_verbose("%sTransmitting (no NAT):\n%s\n to %s:%d\n", reliable ? "Reliably " : "", req->data, inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); + ast_verbose("--- %s Transmitting (no NAT) to %s:%d\n%s\n---\n", reliable ? "Reliably " : "", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port),req->data); + } else { + if (p->nat) + ast_verbose("--- %s Transmitting (NAT) to %s:%d (no headers)\n\n", reliable ? "Reliably " : "", inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); + else + ast_verbose("--- %s Transmitting (no NAT) to %s:%d (no headers)\n", reliable ? "Reliably " : "", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); + } } if (reliable) res = __sip_reliable_xmit(p, seqno, 1, req->data, req->len); @@ -610,10 +623,18 @@ { int res; if (sipdebug) { + if (!sipdebugfilter || ( !strcmp(sipdebugfilter_ip, inet_ntoa(p->recv.sin_addr)) && ntohs(p->recv.sin_port) == sipdebugfilter_port )) { + + if (p->nat) + ast_verbose("---\n* %sTransmitting (NAT) to %s:%d\n%s\n---\n", reliable ? "Reliably " : "", inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port),req->data); + else + ast_verbose("---\n* %sTransmitting (no NAT) to %s:%d\n%s\n---\n", reliable ? "Reliably " : "", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port),req->data); + } else { if (p->nat) - ast_verbose("%sTransmitting:\n%s (NAT) to %s:%d\n", reliable ? "Reliably " : "", req->data, inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); + ast_verbose("---\n* %sTransmitting (NAT) to %s:%d (no headers)\n", reliable ? "Reliably " : "", inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); else - ast_verbose("%sTransmitting:\n%s (no NAT) to %s:%d\n", reliable ? "Reliably " : "", req->data, inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); + ast_verbose("---\n* %sTransmitting (no NAT) to %s:%d (no headers)\n", reliable ? "Reliably " : "", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); + } } if (reliable) res = __sip_reliable_xmit(p, seqno, 0, req->data, req->len); @@ -644,13 +665,13 @@ { struct sip_pvt *p = ast->pvt->pvt; if (sipdebug) - ast_verbose("Sending text %s on %s\n", text, ast->name); + ast_verbose("---\n* Sending text %s on %s\n", text, ast->name); if (!p) return -1; if (!text || !strlen(text)) return 0; if (sipdebug) - ast_verbose("Really sending text %s on %s\n", text, ast->name); + ast_verbose("---\n* Really sending text %s on %s\n", text, ast->name); transmit_message_with_text(p, text); return 0; } @@ -893,7 +914,7 @@ struct sip_pvt *cur, *prev = NULL; struct sip_pkt *cp; if (sipdebug) - ast_log(LOG_DEBUG, "Destorying call '%s'\n", p->callid); + ast_log(LOG_DEBUG, "* Destroying call '%s'\n", p->callid); if (p->stateid > -1) ast_extension_state_del(p->stateid, NULL); if (p->initid > -1) @@ -1824,7 +1845,7 @@ f++; req->lines = f; if (sipdebug) - ast_verbose("%d headers, %d lines\n", req->headers, req->lines); + ast_verbose("** %d headers, %d lines\n", req->headers, req->lines); if (*c) ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); } @@ -1882,7 +1903,7 @@ return -1; } if (sipdebug) - ast_verbose("Found audio format %s\n", ast_getformatname(codec)); + ast_verbose("* Found audio format %s\n", ast_getformatname(codec)); ast_rtp_set_m_type(p->rtp, codec); codecs += len; /* Skip over any whitespace */ @@ -1900,7 +1921,7 @@ return -1; } if (sipdebug) - ast_verbose("Found video format %s\n", ast_getformatname(codec)); + ast_verbose("* Found video format %s\n", ast_getformatname(codec)); ast_rtp_set_m_type(p->vrtp, codec); codecs += len; /* Skip over any whitespace */ @@ -1935,7 +1956,7 @@ } if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue; if (sipdebug) - ast_verbose("Found description format %s\n", mimeSubtype); + ast_verbose("* Found description format %s\n", mimeSubtype); // Note: should really look at the 'freq' and '#chans' params too ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype); if (p->vrtp) @@ -1952,7 +1973,7 @@ p->noncodeccapability = noncodeccapability & (peernoncodeccapability | vpeernoncodeccapability); if (sipdebug) { - ast_verbose("Capabilities: us - %d, them - %d/%d, combined - %d\n", + ast_verbose("* Capabilities: us - %d, them - %d/%d, combined - %d\n", p->capability, peercapability, vpeercapability, p->jointcapability); ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n", noncodeccapability, peernoncodeccapability, @@ -2150,7 +2171,7 @@ /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ if (sipdebug) - ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); + ast_verbose("* set_destination: Parsing <%s> for address/port to send to\n", uri); /* Find and parse hostname */ h = strchr(uri, '@'); @@ -2195,7 +2216,7 @@ memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); p->sa.sin_port = htons(port); if (sipdebug) - ast_verbose("set_destination: set destination to %s, port %d\n", inet_ntoa(p->sa.sin_addr), port); + ast_verbose("* set_destination: set destination to %s, port %d\n", inet_ntoa(p->sa.sin_addr), port); } static int init_resp(struct sip_request *req, char *resp, struct sip_request *orig) @@ -2509,9 +2530,9 @@ } } if (sipdebug) - ast_verbose("We're at %s port %d\n", inet_ntoa(p->ourip), ntohs(sin.sin_port)); + ast_verbose("* We're at %s port %d\n", inet_ntoa(p->ourip), ntohs(sin.sin_port)); if (sipdebug && p->vrtp) - ast_verbose("Video is at %s port %d\n", inet_ntoa(p->ourip), ntohs(vsin.sin_port)); + ast_verbose("* Video is at %s port %d\n", inet_ntoa(p->ourip), ntohs(vsin.sin_port)); snprintf(v, sizeof(v), "v=0\r\n"); snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, inet_ntoa(dest.sin_addr)); snprintf(s, sizeof(s), "s=session\r\n"); @@ -2524,7 +2545,7 @@ while(cur) { if (p->jointcapability & cur->codec) { if (sipdebug) - ast_verbose("Answering with preferred capability %d\n", cur->codec); + ast_verbose("* Answering with preferred capability %d\n", cur->codec); codec = ast_rtp_lookup_code(p->rtp, 1, cur->codec); if (codec > -1) { snprintf(costr, sizeof(costr), " %d", codec); @@ -2546,7 +2567,7 @@ for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) { if ((p->jointcapability & x) && !(alreadysent & x)) { if (sipdebug) - ast_verbose("Answering with capability %d\n", x); + ast_verbose("* Answering with capability %d\n", x); codec = ast_rtp_lookup_code(p->rtp, 1, x); if (codec > -1) { snprintf(costr, sizeof(costr), " %d", codec); @@ -2565,7 +2586,7 @@ for (x = 1; x <= AST_RTP_MAX; x <<= 1) { if (p->noncodeccapability & x) { if (sipdebug) - ast_verbose("Answering with non-codec capability %d\n", x); + ast_verbose("* Answering with non-codec capability %d\n", x); codec = ast_rtp_lookup_code(p->rtp, 0, x); if (codec > -1) { snprintf(costr, sizeof(costr), " %d", codec); @@ -3563,7 +3584,7 @@ transmit_state_notify(p, state, 1); if (option_debug) - ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %d for Notify User %s\n", exten, state, p->username); + ast_verbose(VERBOSE_PREFIX_1 "* Extension Changed %s new state %d for Notify User %s\n", exten, state, p->username); return 0; } @@ -3671,7 +3692,7 @@ *a = '\0'; } if (sipdebug) - ast_verbose("RDNIS is %s\n", c); + ast_verbose("* RDNIS is %s\n", c); strncpy(p->rdnis, c, sizeof(p->rdnis) - 1); return 0; @@ -3717,7 +3738,7 @@ *a = '\0'; } if (sipdebug) - ast_verbose("Looking for %s in %s\n", c, p->context); + ast_verbose("* Looking for %s in %s\n", c, p->context); if (ast_exists_extension(NULL, p->context, c, 1, fr) || !strcmp(c, ast_pickup_ext())) { if (!oreq) @@ -3811,8 +3832,8 @@ if (sipdebug) { - ast_verbose("Looking for %s in %s\n", c, p->context); - ast_verbose("Looking for %s in %s\n", c2, p->context); + ast_verbose("* Looking for %s in %s\n", c, p->context); + ast_verbose("* Looking for %s in %s\n", c2, p->context); } if (strlen(tmp5)) { /* This is a supervised transfer */ @@ -3883,7 +3904,7 @@ *a = '\0'; if (sipdebug) { - ast_verbose("Looking for %s in %s\n", c, p->context); + ast_verbose("* Looking for %s in %s\n", c, p->context); } if (ast_exists_extension(NULL, p->context, c, 1, NULL)) { /* This is an unsupervised transfer */ @@ -3938,9 +3959,9 @@ p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); if (sipdebug) { if (p->nat) - ast_verbose("Sending to %s : %d (NAT)\n", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); + ast_verbose("* Sending to %s : %d (NAT)\n", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); else - ast_verbose("Sending to %s : %d (non-NAT)\n", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); + ast_verbose("* Sending to %s : %d (non-NAT)\n", inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port)); } } return 0; @@ -4130,7 +4151,7 @@ } if (p->owner) { if (sipdebug) - ast_verbose("Message received: '%s'\n", buf); + ast_verbose("* Message received: '%s'\n", buf); memset(&f, 0, sizeof(f)); f.frametype = AST_FRAME_TEXT; f.subclass = 0; @@ -4385,7 +4406,7 @@ if (p->owner) { if (strlen(buf)) { if (sipdebug) - ast_verbose("DTMF received: '%c'\n", buf[0]); + ast_verbose("* DTMF received: '%c'\n", buf[0]); if (buf[0] == '*') event = 10; else if (buf[0] == '#') @@ -4417,7 +4438,11 @@ if (argc != 2) return RESULT_SHOWUSAGE; sipdebug = 1; - ast_cli(fd, "SIP Debugging Enabled\n"); + if (sipdebugfilter) { + ast_cli(fd, "SIP Debugging Enabled. IP %s:%d\n",sipdebugfilter_ip, sipdebugfilter_port); + } else { + ast_cli(fd, "SIP Debugging Enabled\n"); + } return RESULT_SUCCESS; } @@ -4572,11 +4597,11 @@ static char show_peers_usage[] = "Usage: sip show peers\n" -" Lists all known SIP peers.\n"; +" Lists all known SIP peers and their current status.\n"; static char show_reg_usage[] = "Usage: sip show registry\n" -" Lists all registration requests and status.\n"; +" Lists all outbound registration requests and status.\n"; static char debug_usage[] = "Usage: sip debug\n" @@ -4897,7 +4922,7 @@ } } else { if (sipdebug) - ast_verbose("Message is %s\n", msg); + ast_verbose("* Message is %s\n", msg); switch(resp) { case 200: if (!strcasecmp(msg, "INVITE") || !strcasecmp(msg, "REGISTER") ) @@ -4953,6 +4978,9 @@ return 0; } +/* + * Handle SIP requests (methods) + */ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin) { /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things @@ -4962,6 +4990,7 @@ char *cseq; char *from; char *e; + char *useragent; struct ast_channel *c=NULL; struct ast_channel *transfer_to; int seqno; @@ -5065,7 +5094,7 @@ if (!ignore) { /* Use this as the basis */ if (sipdebug) - ast_verbose("Using latest request as basis request\n"); + ast_verbose("* Using latest request as basis request\n"); /* This call is no longer outgoing if it ever was */ p->outgoing = 0; copy_request(&p->initreq, req); @@ -5075,13 +5104,13 @@ return -1; } else { p->jointcapability = p->capability; - ast_log(LOG_DEBUG, "Hm.... No sdp for the moemnt\n"); + ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); } /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ if (p->owner) ast_queue_frame(p->owner, &af, 0); } else if (sipdebug) - ast_verbose("Ignoring this request\n"); + ast_verbose("* Ignoring this request\n"); if (!p->lastinvite) { /* Handle authentication if this is our first invite */ res = check_user(p, req, cmd, e, 1, sin); @@ -5286,20 +5315,20 @@ transmit_response(p, "200 OK", req); } else if (!strcasecmp(cmd, "MESSAGE")) { if (sipdebug) - ast_verbose("Receiving message!\n"); + ast_verbose("* Receiving message!\n"); receive_message(p, req); transmit_response(p, "200 OK", req); } else if (!strcasecmp(cmd, "SUBSCRIBE")) { if (!ignore) { /* Use this as the basis */ if (sipdebug) - ast_verbose("Using latest SUBSCRIBE request as basis request\n"); + ast_verbose("* Using latest SUBSCRIBE request as basis request\n"); /* This call is no longer outgoing if it ever was */ p->outgoing = 0; copy_request(&p->initreq, req); check_via(p, req); } else if (sipdebug) - ast_verbose("Ignoring this request\n"); + ast_verbose("* Ignoring this request\n"); if (!p->lastinvite) { /* Handle authentication if this is our first subscribe */ @@ -5365,6 +5394,7 @@ ast_verbose("Using latest request as basis request\n"); copy_request(&p->initreq, req); check_via(p, req); + if ((res = register_verify(p, sin, req, e)) < 0) ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s'\n", get_header(req, "To"), inet_ntoa(sin->sin_addr)); if (res < 1) { @@ -5417,8 +5447,14 @@ } req.data[res] = '\0'; req.len = res; - if (sipdebug) - ast_verbose("Sip read: \n%s\n", req.data); + /* Limit debug */ + if (sipdebug) { + if (!sipdebugfilter || ( !strcmp(sipdebugfilter_ip, inet_ntoa(sin.sin_addr)) && ntohs(sin.sin_port) == sipdebugfilter_port ) ) { + ast_verbose("\n\n--- Sip read from %s:%d \n%s\n---\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); + } else { + ast_verbose("\n\n--- Sip read from %s:%d (no headers)\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port) ); + } + } parse(&req); if (req.headers < 2) { /* Must have at least two headers */ @@ -6187,6 +6223,12 @@ capability &= ~format; sip_pref_remove(format); } + } else if (!strcasecmp(v->name, "sipdebugip")) { + strncpy(sipdebugfilter_ip, v->value, sizeof(sipdebugfilter_ip) - 1); + sipdebugfilter = 1; + } else if (!strcasecmp(v->name, "sipdebugport")) { + sipdebugfilter_port = atoi(v->value); + sipdebugfilter = 1; } else if (!strcasecmp(v->name, "register")) { sip_register(v->value, v->lineno); } else if (!strcasecmp(v->name, "tos")) {