/* returns -1 on error. */ int osip_message_set_contact(osip_message_t * sip, const char *hvalue) { int i; osip_contact_t *contact; if (hvalue == NULL || hvalue[0] == '\0') return OSIP_SUCCESS; i = osip_contact_init(&contact); if (i != 0) return i; i = osip_contact_parse(contact, hvalue); if (i != 0) { osip_contact_free(contact); return i; } sip->message_property = 2; osip_list_add(&sip->contacts, contact, -1); return OSIP_SUCCESS; /* ok */ }
int generating_register (eXosip_reg_t * jreg, osip_message_t ** reg, char *transport, char *from, char *proxy, char *contact, int expires) { int i; char locip[65]; char firewall_ip[65]; char firewall_port[10]; if (eXosip.eXtl == NULL) return OSIP_NO_NETWORK; if (eXosip.eXtl->tl_get_masquerade_contact != NULL) { eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip), firewall_port, sizeof (firewall_port)); } i = generating_request_out_of_dialog (reg, "REGISTER", NULL, transport, from, proxy); if (i != 0) return i; memset (locip, '\0', sizeof (locip)); eXosip_guess_ip_for_via (eXosip.eXtl->proto_family, locip, 49); if (locip[0] == '\0') { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: no default interface defined\n")); osip_message_free (*reg); *reg = NULL; return OSIP_NO_NETWORK; } if (contact == NULL) { osip_contact_t *new_contact = NULL; osip_uri_t *new_contact_url = NULL; i = osip_contact_init (&new_contact); if (i == 0) i = osip_uri_init (&new_contact_url); new_contact->url = new_contact_url; if (i == 0 && (*reg)->from != NULL && (*reg)->from->url != NULL && (*reg)->from->url->username != NULL) { new_contact_url->username = osip_strdup ((*reg)->from->url->username); } if (i == 0 && (*reg)->from != NULL && (*reg)->from->url != NULL) { /* serach for correct ip */ if (firewall_ip[0] != '\0') { char *c_address = (*reg)->req_uri->host; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; i = eXosip_get_addrinfo (&addrinfo, (*reg)->req_uri->host, 5060, IPPROTO_UDP); if (i == 0) { memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); eXosip_freeaddrinfo (addrinfo); c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "eXosip: here is the resolved destination host=%s\n", c_address)); } if (eXosip_is_public_address (c_address)) { new_contact_url->host = osip_strdup (firewall_ip); new_contact_url->port = osip_strdup (firewall_port); } else { new_contact_url->host = osip_strdup (locip); new_contact_url->port = osip_strdup (firewall_port); } } else { new_contact_url->host = osip_strdup (locip); new_contact_url->port = osip_strdup (firewall_port); } if (transport != NULL && osip_strcasecmp (transport, "UDP") != 0) { osip_uri_uparam_add (new_contact_url, osip_strdup ("transport"), osip_strdup (transport)); } if (jreg->r_line[0] != '\0') { osip_uri_uparam_add (new_contact_url, osip_strdup ("line"), osip_strdup (jreg->r_line)); } osip_list_add (&(*reg)->contacts, new_contact, -1); } } else { osip_message_set_contact (*reg, contact); } { char exp[10]; /* MUST never be ouside 1 and 3600 */ snprintf (exp, 9, "%i", expires); osip_message_set_expires (*reg, exp); } osip_message_set_content_length (*reg, "0"); return OSIP_SUCCESS; }
/* private plugin code */ static int plugin_regex_redirect(sip_ticket_t *ticket) { osip_uri_t *to_url=ticket->sipmsg->to->url; char *url_string=NULL; osip_uri_t *new_to_url; int i, sts; osip_contact_t *contact = NULL; /* character workspaces for regex */ #define WORKSPACE_SIZE 128 static char in[WORKSPACE_SIZE+1], rp[WORKSPACE_SIZE+1]; /* do apply to full To URI... */ sts = osip_uri_to_str(to_url, &url_string); if (sts != 0) { ERROR("osip_uri_to_str() failed"); return STS_FAILURE; } DEBUGC(DBCLASS_BABBLE, "To URI string: [%s]", url_string); /* perform search and replace of the regexes, first match hits */ for (i = 0; i < plugin_cfg.regex_pattern.used; i++) { regmatch_t *pmatch = NULL; pmatch = rmatch(url_string, WORKSPACE_SIZE, &re[i]); if (pmatch == NULL) continue; /* no match, next */ /* have a match, do the replacement */ INFO("Matched rexec rule: %s",plugin_cfg.regex_desc.string[i] ); strncpy (in, url_string, WORKSPACE_SIZE); in[WORKSPACE_SIZE]='\0'; strncpy (rp, plugin_cfg.regex_replace.string[i], WORKSPACE_SIZE); rp[WORKSPACE_SIZE]='\0'; sts = rreplace(in, WORKSPACE_SIZE, &re[i], pmatch, rp); if (sts != STS_SUCCESS) { ERROR("regex replace failed: pattern:[%s] replace:[%s]", plugin_cfg.regex_pattern.string[i], plugin_cfg.regex_replace.string[i]); osip_free(url_string); return STS_FAILURE; } /* only do first match */ break; } if (i >= plugin_cfg.regex_pattern.used) { /* no match */ osip_free(url_string); return STS_SUCCESS; } /* in: contains the new string */ sts = osip_uri_init(&new_to_url); if (sts != 0) { ERROR("Unable to initialize URI"); osip_free(url_string); return STS_FAILURE; } sts = osip_uri_parse(new_to_url, in); if (sts != 0) { ERROR("Unable to parse To URI: %s", in); osip_uri_free(new_to_url); osip_free(url_string); return STS_FAILURE; } /* use a "302 Moved temporarily" response back to the client */ /* new target is within the Contact Header */ /* remove all Contact headers in message */ for (i=0; (contact != NULL) || (i == 0); i++) { osip_message_get_contact(ticket->sipmsg, 0, &contact); if (contact) { osip_list_remove(&(ticket->sipmsg->contacts),0); osip_contact_free(contact); } } /* for i */ /* insert one new Contact header containing the new target address */ osip_contact_init(&contact); osip_list_add(&(ticket->sipmsg->contacts),contact,0); /* link the new_to_url into the Contact list */ contact->url = new_to_url; new_to_url = NULL; /* * Add the 'REDIRECTED_TAG=REDIRECTED_VAL' parameter to URI. Required to figure out * if this INVITE has already been processed (redirected) and * does not need further attention by this plugin. * THIS IS REQUIRED TO AVOID A LOOP */ osip_uri_param_add(&(contact->url->url_params), osip_strdup(REDIRECTED_TAG), osip_strdup(REDIRECTED_VAL)); INFO("redirecting %s -> %s", url_string, in); /* sent redirect message back to local client */ add_to_redirected_cache(&redirected_cache, ticket); sip_gen_response(ticket, 302 /*Moved temporarily*/); /* release resources and return */ osip_free(url_string); return STS_SIP_SENT; }
/* * SIP_REWRITE_CONTACT * * rewrite the Contact header * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int sip_rewrite_contact (sip_ticket_t *ticket, int direction, struct in_addr *local_ip) { osip_message_t *sip_msg=ticket->sipmsg; osip_contact_t *contact; int i; #if UNREG_WITHOUT_REG_HG522 char tmpUserName[128] = {0}; char tmpPort[6] = {0}; #endif if (sip_msg == NULL) return STS_FAILURE; osip_message_get_contact(sip_msg, 0, &contact); if (contact == NULL) { printsip("sip: rewrite_contact contact is NULL \r\n"); return STS_FAILURE; } for (i=0;i<URLMAP_SIZE;i++){ if (urlmap[i].active == 0) continue; if ((direction == DIR_OUTGOING) && (compare_url(contact->url, urlmap[i].true_url)==STS_SUCCESS)) break; if ((direction == DIR_INCOMING) && (compare_url(contact->url, urlmap[i].masq_url)==STS_SUCCESS)) break; #if UNREG_WITHOUT_REG_HG522 if ((direction == DIR_OUTGOING) && (NULL != contact->url) && (NULL != urlmap[i].true_url) && (NULL != contact->url->host) && (NULL != urlmap[i].true_url->host) && (strcmp(contact->url->host, urlmap[i].true_url->host) == 0)) { strcpy(tmpUserName, contact->url->username); if (NULL != contact->url->port) { strncpy(tmpPort, contact->url->port, 6); } break; } #endif } /* found a mapping entry */ if (i<URLMAP_SIZE) { char *tmp; if (NULL != contact->url) { printsip("************* sip: rewrote Contact header %s@%s:%s -> %s@%s:%s \r\n", (contact->url->username)? contact->url->username : "******", (contact->url->host)? contact->url->host : "*NULL*", (contact->url->port)? contact->url->port : "NULL port", urlmap[i].masq_url->username, urlmap[i].masq_url->host, (urlmap[i].masq_url->port)? urlmap[i].masq_url->port : "NULL port"); } /* remove old entry */ osip_list_remove(sip_msg->contacts,0); osip_contact_to_str(contact, &tmp); osip_contact_free(contact); /* clone the url from urlmap */ osip_contact_init(&contact); osip_contact_parse(contact,tmp); osip_free(tmp); osip_uri_free(contact->url); if (direction == DIR_OUTGOING) { /* outgoing, use masqueraded url */ osip_uri_clone(urlmap[i].masq_url, &contact->url); if (local_ip != NULL) { char *ip = malloc(20); strncpy(ip, inet_ntoa(*local_ip), 20); free(contact->url->host); contact->url->host = ip; } #if UNREG_WITHOUT_REG_HG522 if ('\0' != tmpUserName[0]) { char *username = malloc(strlen(tmpUserName)+1); strncpy(username, tmpUserName, strlen(tmpUserName)+1); free(contact->url->username); contact->url->username = username; } if ((NULL == urlmap[i].masq_url->port) && ('\0' != tmpPort[0])) { char *port = malloc(strlen(tmpPort)+1); strncpy(port, tmpPort, strlen(tmpPort)+1); contact->url->port = port; } #endif } else { /* incoming, use true url */ osip_uri_clone(urlmap[i].true_url, &contact->url); printsip("incoming: osip_uri_clone from %s \r\n", urlmap[i].true_url->host); } osip_list_add(sip_msg->contacts,contact,-1); } else { return STS_FAILURE; } return STS_SUCCESS; }
/* * SIP_REWRITE_CONTACT * * rewrite the Contact header * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int sip_rewrite_contact (sip_ticket_t *ticket, int direction) { osip_message_t *sip_msg=ticket->sipmsg; osip_contact_t *contact; int i, j; int replaced=0; if (sip_msg == NULL) return STS_FAILURE; /* at least one contact header present? */ osip_message_get_contact(sip_msg, 0, &contact); if (contact == NULL) return STS_FAILURE; /* loop for all existing contact headers in message */ for (j=0; contact != NULL; j++) { osip_message_get_contact(sip_msg, j, &contact); if (contact == NULL) break; if (contact->url == NULL) continue; /* search for an entry */ for (i=0;i<URLMAP_SIZE;i++){ if (urlmap[i].active == 0) continue; if ((direction == DIR_OUTGOING) && (compare_url(contact->url, urlmap[i].true_url)==STS_SUCCESS)) break; if ((direction == DIR_INCOMING) && (compare_url(contact->url, urlmap[i].masq_url)==STS_SUCCESS)) break; } /* found a mapping entry */ if (i<URLMAP_SIZE) { char *tmp; if (direction == DIR_OUTGOING) { DEBUGC(DBCLASS_PROXY, "rewriting Contact header %s@%s -> %s@%s", (contact->url->username)? contact->url->username : "******", (contact->url->host)? contact->url->host : "*NULL*", urlmap[i].masq_url->username, urlmap[i].masq_url->host); } else { DEBUGC(DBCLASS_PROXY, "rewriting Contact header %s@%s -> %s@%s", (contact->url->username)? contact->url->username : "******", (contact->url->host)? contact->url->host : "*NULL*", urlmap[i].true_url->username, urlmap[i].true_url->host); } /* remove old entry */ osip_list_remove(sip_msg->contacts,j); osip_contact_to_str(contact, &tmp); osip_contact_free(contact); /* clone the url from urlmap*/ osip_contact_init(&contact); osip_contact_parse(contact,tmp); osip_free(tmp); osip_uri_free(contact->url); if (direction == DIR_OUTGOING) { /* outgoing, use masqueraded url */ osip_uri_clone(urlmap[i].masq_url, &contact->url); } else { /* incoming, use true url */ osip_uri_clone(urlmap[i].true_url, &contact->url); } osip_list_add(sip_msg->contacts,contact,j); replaced=1; } } if (replaced == 0) { DEBUGC(DBCLASS_PROXY, "no Contact header rewritten"); return STS_FAILURE; } return STS_SUCCESS; }