📄 register.c
字号:
} if ( (j < 0) && (i >= URLMAP_SIZE) ) { /* oops, no free entries left... */ ERROR("URLMAP is full - registration failed"); return STS_FAILURE; } if (i >= URLMAP_SIZE) { /* entry not existing, create new one */ i=j; /* write entry */ urlmap[i].active=1; /* Contact: field */ osip_uri_clone( ((osip_contact_t*) (ticket->sipmsg->contacts->node->element))->url, &urlmap[i].true_url); /* To: field */ osip_uri_clone( ticket->sipmsg->to->url, &urlmap[i].reg_url); DEBUGC(DBCLASS_REG,"create new entry for %s@%s <-> %s@%s at slot=%i", (url1_contact->username) ? url1_contact->username : "*NULL*", (url1_contact->host) ? url1_contact->host : "*NULL*", (urlmap[i].reg_url->username) ? urlmap[i].reg_url->username : "*NULL*", (urlmap[i].reg_url->host) ? urlmap[i].reg_url->host : "*NULL*", i); /* * try to figure out if we ought to do some masquerading */ osip_uri_clone( ticket->sipmsg->to->url, &urlmap[i].masq_url); n=configuration.mask_host.used; if (n != configuration.masked_host.used) { ERROR("# of mask_host is not equal to # of masked_host in config!"); n=0; } DEBUG("%i entries in MASK config table", n); for (j=0; j<n; j++) { DEBUG("compare [%s] <-> [%s]",configuration.mask_host.string[j], ticket->sipmsg->to->url->host); if (strcmp(configuration.mask_host.string[j], ticket->sipmsg->to->url->host)==0) break; } if (j<n) { /* we are masquerading this UA, replace the host part of the url */ DEBUGC(DBCLASS_REG,"masquerading UA %s@%s as %s@%s", (url1_contact->username) ? url1_contact->username : "*NULL*", (url1_contact->host) ? url1_contact->host : "*NULL*", (url1_contact->username) ? url1_contact->username : "*NULL*", configuration.masked_host.string[j]); urlmap[i].masq_url->host=realloc(urlmap[i].masq_url->host, strlen(configuration.masked_host.string[j])+1); strcpy(urlmap[i].masq_url->host, configuration.masked_host.string[j]); } } else { /* if new entry */ /* This is an existing entry */ /* * Some phones (like BudgeTones *may* dynamically grab a SIP port * so we might want to update the true_url and reg_url each time * we get an REGISTER */ /* Contact: field (true_url) */ osip_uri_free(urlmap[i].true_url); osip_uri_clone( ((osip_contact_t*) (ticket->sipmsg->contacts->node->element))->url, &urlmap[i].true_url); /* To: field (reg_url) */ osip_uri_free(urlmap[i].reg_url); osip_uri_clone( ticket->sipmsg->to->url, &urlmap[i].reg_url); } /* * for proxying: force device to be masqueraded * as with the outbound IP (masq_url) */ if (force_lcl_masq) { struct in_addr addr; char *addrstr; if (get_interface_ip(IF_OUTBOUND, &addr) != STS_SUCCESS) { return STS_FAILURE; } /* host part */ addrstr = utils_inet_ntoa(addr); DEBUGC(DBCLASS_REG,"masquerading UA %s@%s local %s@%s", (url1_contact->username) ? url1_contact->username : "*NULL*", (url1_contact->host) ? url1_contact->host : "*NULL*", (url1_contact->username) ? url1_contact->username : "*NULL*", addrstr); urlmap[i].masq_url->host=realloc(urlmap[i].masq_url->host, strlen(addrstr)+1); strcpy(urlmap[i].masq_url->host, addrstr); /* port number if required */ if (configuration.sip_listen_port != SIP_PORT) { urlmap[i].masq_url->port=realloc(urlmap[i].masq_url->port, 16); sprintf(urlmap[i].masq_url->port, "%i", configuration.sip_listen_port); } } /* give some safety margin for the next update */ if (expires > 0) expires+=30; /* update registration timeout */ urlmap[i].expires=time_now+expires; /* * un-REGISTER */ } else { /* expires > 0 */ /* * Remove registration * Siproxd will ALWAYS remove ALL bindings for a given * address-of-record */ for (i=0; i<URLMAP_SIZE; i++) { if (urlmap[i].active == 0) continue; url2_to=urlmap[i].reg_url; if (compare_url(url1_to, url2_to)==STS_SUCCESS) { DEBUGC(DBCLASS_REG, "removing registration for %s@%s at slot=%i", (url2_to->username) ? url2_to->username : "*NULL*", (url2_to->host) ? url2_to->host : "*NULL*", i); urlmap[i].expires=0; break; } } } return STS_SUCCESS;}/* * cyclically called to do the aging of the URL mapping table entries * and throw out expired entries. * Also we do the cyclic saving here - if required. */void register_agemap(void) { int i; time_t t; /* expire old entries */ time(&t); DEBUGC(DBCLASS_BABBLE,"sip_agemap, t=%i",(int)t); for (i=0; i<URLMAP_SIZE; i++) { if ((urlmap[i].active == 1) && (urlmap[i].expires < t)) { DEBUGC(DBCLASS_REG,"cleaned entry:%i %s@%s", i, urlmap[i].masq_url->username, urlmap[i].masq_url->host); urlmap[i].active=0; osip_uri_free(urlmap[i].true_url); osip_uri_free(urlmap[i].masq_url); osip_uri_free(urlmap[i].reg_url); } } /* auto-save of registration table */ if ((configuration.autosave_registrations > 0) && ((last_save + configuration.autosave_registrations) < t)) { DEBUGC(DBCLASS_REG,"auto-saving registration table"); register_save(); last_save = t; } return;}/* * send answer to a registration request. * flag = STS_SUCCESS -> positive answer (200) * flag = STS_FAILURE -> negative answer (503) * flag = STS_NEED_AUTH -> proxy authentication needed (407) * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */int register_response(sip_ticket_t *ticket, int flag) { osip_message_t *response; int code; int sts; osip_via_t *via; int port; char *buffer; size_t buflen; struct in_addr addr; osip_header_t *expires_hdr; /* ok -> 200, fail -> 503 */ switch (flag) { case STS_SUCCESS: code = 200; /* OK */ break; case STS_FAILURE: code = 503; /* failed */ break; case STS_NEED_AUTH: code = 407; /* proxy authentication needed */ break; default: code = 503; /* failed */ break; } /* create the response template */ if ((response=msg_make_template_reply(ticket, code))==NULL) { ERROR("register_response: error in msg_make_template_reply"); return STS_FAILURE; } /* insert the expiration header */ osip_message_get_expires(ticket->sipmsg, 0, &expires_hdr); if (expires_hdr) { osip_message_set_expires(response, expires_hdr->hvalue); } /* if we send back an proxy authentication needed, include the Proxy-Authenticate field */ if (code == 407) { auth_include_authrq(response); } /* get the IP address from existing VIA header */ osip_message_get_via (response, 0, &via); if (via == NULL) { ERROR("register_response: Cannot send response - no via field"); return STS_FAILURE; } /* name resolution needed? */ if (utils_inet_aton(via->host,&addr) == 0) { /* yes, get IP address */ sts = get_ip_by_host(via->host, &addr); if (sts == STS_FAILURE) { DEBUGC(DBCLASS_REG, "register_response: cannot resolve VIA [%s]", via->host); return STS_FAILURE; } } sts = sip_message_to_str(response, &buffer, &buflen); if (sts != 0) { ERROR("register_response: msg_2char failed"); return STS_FAILURE; } /* send answer back */ if (via->port) { port=atoi(via->port); if ((port<=0) || (port>65535)) port=SIP_PORT; } else { port=configuration.sip_listen_port; } sipsock_send(addr, port, ticket->protocol, buffer, buflen); /* free the resources */ osip_message_free(response); free(buffer); return STS_SUCCESS;}/* * set expiration timeout as received with SIP response * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */int register_set_expire(sip_ticket_t *ticket) { int i, j; int expires=-1; osip_contact_t *contact=NULL; time_t time_now; osip_header_t *expires_hdr=NULL; osip_uri_param_t *expires_param=NULL; if (ticket->direction != RESTYP_INCOMING) { WARN("register_set_expire called with != incoming response"); return STS_FAILURE; } time(&time_now); DEBUGC(DBCLASS_REG,"REGISTER response, looking for 'Expire' information"); /* evaluate Expires Header field */ osip_message_get_expires(ticket->sipmsg, 0, &expires_hdr); /* loop for all existing contact headers in message */ for (j=0; (contact != NULL) || (j==0); j++) { osip_message_get_contact(ticket->sipmsg, j, &contact); /* * look for an Contact expires parameter - in case of REGISTER * these two are equal. The Contact expires has higher priority! */ if (contact==NULL) continue; osip_contact_param_get_byname(contact, EXPIRES, &expires_param); if (expires_param && expires_param->gvalue) { /* get expires from contact Header */ expires=atoi(expires_param->gvalue); if ((expires < 0) || (expires >= LONG_MAX)) expires=configuration.default_expires; } else if (expires_hdr && expires_hdr->hvalue) { /* get expires from expires Header */ expires=atoi(expires_hdr->hvalue); if ((expires < 0) || (expires >= LONG_MAX)) expires=configuration.default_expires; } DEBUGC(DBCLASS_REG,"Expires=%i, expires_param=%p, expires_hdr=%p", expires, expires_param, expires_hdr); if (expires > 0) { /* search for an entry */ for (i=0;i<URLMAP_SIZE;i++){ if (urlmap[i].active == 0) continue; if ((compare_url(contact->url, urlmap[i].masq_url)==STS_SUCCESS)) break; } /* found a mapping entry */ if (i<URLMAP_SIZE) { /* update registration timeout */ DEBUGC(DBCLASS_REG,"changing registration timeout to %i" " entry [%i]", expires, i); urlmap[i].expires=time_now+expires; } else { DEBUGC(DBCLASS_REG,"no urlmap entry found"); } } } /* for j */ return STS_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -