static int tcp_tl_send_message(osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket) { size_t length = 0; char *message; int i; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5060; } /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route=NULL; osip_generic_param_t *tag=NULL; osip_message_get_route (sip, 0, &route); osip_to_get_tag (sip->to, &tag); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_remove(&sip->routes, 0); } i = osip_message_to_str (sip, &message, &length); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_add(&sip->routes, route, 0); } } if (i != 0 || length <= 0) { return -1; } /* Step 1: find existing socket to send message */ if (out_socket <= 0) { out_socket = _tcp_tl_find_socket (host, port); /* Step 2: create new socket with host:port */ if (out_socket <= 0) { out_socket = _tcp_tl_connect_socket (host, port); } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (to dest=%s:%i)\n", message, host, port)); } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (reusing REQUEST connection)\n", message)); } if (out_socket <= 0) { return -1; } if (0 > send (out_socket, (const void *) message, length, 0)) { #ifdef WIN32 if (WSAECONNREFUSED == WSAGetLastError ()) #else if (ECONNREFUSED == errno) #endif { /* This can be considered as an error, but for the moment, I prefer that the application continue to try sending message again and again... so we are not in a error case. Nevertheless, this error should be announced! ALSO, UAS may not have any other options than retry always on the same port. */ osip_free (message); return 1; } else { /* SIP_NETWORK_ERROR; */ #if !defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "TCP error: \n%s\n", strerror (errno))); #endif osip_free (message); return -1; } } osip_free (message); return 0; }
PPL_DECLARE (int) psp_core_event_add_sip_message (osip_event_t * evt) { osip_transaction_t *transaction; osip_message_t *answer1xx; int i; if (MSG_IS_REQUEST (evt->sip)) { /* delete request where cseq method does not match the method in request-line */ if (evt->sip->cseq==NULL || evt->sip==NULL || evt->sip->cseq->method==NULL || evt->sip->sip_method==NULL) { osip_event_free (evt); return -1; } if (0 != strcmp (evt->sip->cseq->method, evt->sip->sip_method)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "core module: Discard invalid message with method!=cseq!\n")); osip_event_free (evt); return -1; } } i = psp_core_find_osip_transaction_and_add_event (evt); if (i == 0) { psp_osip_wakeup (core->psp_osip); return 0; /*evt consumed */ } if (MSG_IS_REQUEST (evt->sip)) { if (MSG_IS_ACK (evt->sip)) { /* continue as it is a new transaction... */ osip_route_t *route; /* If a route header is present, then plugins will give the correct location. */ osip_message_get_route (evt->sip, 0, &route); if (route == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "core module: This is a late ACK to discard!\n")); /* It can be a ACK for 200 ok, but those ACK SHOULD never go through this proxy! (and should be sent to the contact header of the 200ok */ #ifdef SUPPORT_FOR_BROKEN_UA /* if this ACK has a request-uri that is not us, forward the message there. How should I modify this message?? */ if (evt!=NULL && evt->sip!=NULL && evt->sip!=NULL && evt->sip->req_uri!=NULL) { if (psp_core_is_responsible_for_this_domain(evt->sip->req_uri)!=0) { int port = 5060; if (evt->sip->req_uri->port != NULL) port = osip_atoi (evt->sip->req_uri->port); psp_core_cb_snd_message(NULL, evt->sip, evt->sip->req_uri->host, port, -1); } } #endif osip_event_free (evt); return 0; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "core module: This is a ACK for INVITE!\n")); psp_core_event_add_sfp_inc_ack (evt->sip); osip_free (evt); return 0; } /* we can create the transaction and send a 1xx */ transaction = osip_create_transaction (core->psp_osip->osip, evt); if (transaction == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL, "core module: Could not create a transaction for this request!\n")); osip_event_free (evt); return -1; } /* now, all retransmissions will be handled by oSIP. */ /* From rfc3261: (Section: 16.2) "Thus, a stateful proxy SHOULD NOT generate 100 (Trying) responses to non-INVITE requests." */ if (MSG_IS_INVITE (evt->sip)) { i = osip_msg_build_response (&answer1xx, 100, evt->sip); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "sfp module: could not create a 100 Trying for this transaction. (discard it and let the transaction die itself)!\n")); osip_event_free (evt); return -1; } osip_transaction_add_event (transaction, evt); evt = osip_new_outgoing_sipmessage (answer1xx); evt->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, evt); } else osip_transaction_add_event (transaction, evt); psp_osip_wakeup (core->psp_osip); return 0; } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL, "sfp module: No module seems to be able to forward this response!\n")); /* this is probably a late answer? */ /* let's forward it! */ i = psp_core_handle_late_answer (evt->sip); if (i != 0) { osip_event_free (evt); return -1; } osip_event_free (evt); } return 0; }
static int udp_tl_send_message (osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket) { int len = 0; size_t length = 0; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; char *message; char *crypt_date; char ipbuf[INET6_ADDRSTRLEN]; int i; if (udp_socket <= 0) return -1; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5060; } eXtl_update_local_target (sip); i = -1; #ifndef MINISIZE if (tr != NULL && tr->record.name[0] != '\0' && tr->record.srventry[0].srv[0] != '\0') { /* always choose the first here. if a network error occur, remove first entry and replace with next entries. */ osip_srv_entry_t *srv; int n = 0; for (srv = &tr->record.srventry[0]; n < 10 && tr->record.srventry[0].srv[0]; srv = &tr->record.srventry[0]) { i = eXosip_get_addrinfo (&addrinfo, srv->srv, srv->port, IPPROTO_UDP); if (i == 0) { host = srv->srv; port = srv->port; break; } memmove (&tr->record.srventry[0], &tr->record.srventry[1], 9 * sizeof (osip_srv_entry_t)); memset (&tr->record.srventry[9], 0, sizeof (osip_srv_entry_t)); i = -1; /* copy next element */ n++; } } #endif /* if SRV was used, distination may be already found */ if (i != 0) { i = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_UDP); } if (i != 0) { return -1; } memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); len = addrinfo->ai_addrlen; eXosip_freeaddrinfo (addrinfo); /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route = NULL; osip_generic_param_t *tag = NULL; osip_message_get_route (sip, 0, &route); osip_to_get_tag (sip->to, &tag); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_remove (&sip->routes, 0); } i = osip_message_to_str (sip, &message, &length); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_add (&sip->routes, route, 0); } } if (i != 0 || length <= 0) { return -1; } switch (((struct sockaddr *) &addr)->sa_family) { case AF_INET: inet_ntop (((struct sockaddr *) &addr)->sa_family, &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf, sizeof (ipbuf)); break; case AF_INET6: inet_ntop (((struct sockaddr *) &addr)->sa_family, &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf, sizeof (ipbuf)); break; default: strncpy (ipbuf, "(unknown)", sizeof (ipbuf)); break; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: (to dest=%s:%i)\n%s\n", ipbuf, port, message)); if (tr != NULL) { if (tr->ict_context != NULL) osip_ict_set_destination (tr->ict_context, osip_strdup (ipbuf), port); if (tr->nict_context != NULL) osip_nict_set_destination (tr->nict_context, osip_strdup (ipbuf), port); } //SIP加密点 crypt_date = (char *)malloc(length); memcpy(crypt_date,(const char *)message, length); #ifdef ENABLE_MYCRYPT CRYPT_DATA_SIP((unsigned char *)crypt_date,length); #endif // ENABLE_MYCRYPT if (0 > sendto (udp_socket, (const void *) crypt_date, length, 0, (struct sockaddr *) &addr, len)) { #ifdef WIN32 if (WSAECONNREFUSED == WSAGetLastError ()) #else if (ECONNREFUSED == errno) #endif { /* This can be considered as an error, but for the moment, I prefer that the application continue to try sending message again and again... so we are not in a error case. Nevertheless, this error should be announced! ALSO, UAS may not have any other options than retry always on the same port. */ osip_free (message); return 1; } else { #ifndef MINISIZE /* delete first SRV entry that is not reachable */ if (tr != NULL && tr->record.name[0] != '\0' && tr->record.srventry[0].srv[0] != '\0') { memmove (&tr->record.srventry[0], &tr->record.srventry[1], 9 * sizeof (osip_srv_entry_t)); memset (&tr->record.srventry[9], 0, sizeof (osip_srv_entry_t)); osip_free (message); return OSIP_SUCCESS; /* retry for next retransmission! */ } #endif /* SIP_NETWORK_ERROR; */ osip_free (message); return -1; } } if (eXosip.keep_alive > 0) { if (MSG_IS_REGISTER (sip)) { eXosip_reg_t *reg = NULL; if (_eXosip_reg_find (®, tr) == 0) { memcpy (&(reg->addr), &addr, len); reg->len = len; } } } osip_free (message); return OSIP_SUCCESS; }
int _eXosip_call_retry_request (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * out_tr) { osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; int cseq; osip_via_t *via; osip_contact_t *co; int pos; int i; int protocol = IPPROTO_UDP; if (jc == NULL) return OSIP_BADPARAMETER; if (jd != NULL) { if (jd->d_out_trs == NULL) return OSIP_BADPARAMETER; } if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return OSIP_BADPARAMETER; i = osip_message_clone (out_tr->orig_request, &msg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return i; } via = (osip_via_t *) osip_list_get (&msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return OSIP_SYNTAXERROR; } if (MSG_IS_STATUS_3XX (out_tr->last_response)) { co = NULL; pos = 0; while (!osip_list_eol (&out_tr->last_response->contacts, pos)) { co = (osip_contact_t *) osip_list_get (&out_tr->last_response->contacts, pos); if (co != NULL && co->url != NULL) { /* check tranport? Only allow UDP, right now */ osip_uri_param_t *u_param; int pos2; u_param = NULL; pos2 = 0; while (!osip_list_eol (&co->url->url_params, pos2)) { u_param = (osip_uri_param_t *) osip_list_get (&co->url->url_params, pos2); if (u_param == NULL || u_param->gname == NULL || u_param->gvalue == NULL) { u_param = NULL; /* skip */ } else if (0 == osip_strcasecmp (u_param->gname, "transport")) { if (0 == osip_strcasecmp (u_param->gvalue, "udp")) { u_param = NULL; protocol = IPPROTO_UDP; break; /* ok */ } else if (0 == osip_strcasecmp (u_param->gvalue, "tcp")) { protocol = IPPROTO_TCP; u_param = NULL; } break; } pos2++; } if (u_param == NULL || u_param->gname == NULL || u_param->gvalue == NULL) { break; /* default is udp! */ } } pos++; co = NULL; } if (co == NULL || co->url == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: contact header\n")); return OSIP_SYNTAXERROR; } /* TODO: remove extra parameter from new request-uri check usual parameter like "transport" */ if (msg->req_uri != NULL && msg->req_uri->host != NULL && co->url->host != NULL && 0 == osip_strcasecmp (co->url->host, msg->req_uri->host)) { osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname (co->url, "maddr", &maddr_param); if (maddr_param != NULL && maddr_param->gvalue != NULL) { /* This is a redirect server, the route should probably be removed? */ osip_route_t *route = NULL; osip_generic_param_t *tag = NULL; osip_message_get_route (msg, 0, &route); if (route != NULL) { osip_to_get_tag (msg->to, &tag); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_remove (&msg->routes, 0); osip_route_free (route); } } } } /* replace request-uri with NEW contact address */ osip_uri_free (msg->req_uri); msg->req_uri = NULL; osip_uri_clone (co->url, &msg->req_uri); /* support for diversions headers/draft! */ { int count = 0; pos = 0; while (!osip_list_eol (&out_tr->last_response->headers, pos)) { osip_header_t *copy = NULL; osip_header_t *head = osip_list_get (&out_tr->last_response->headers, pos); if (head != NULL && 0 == osip_strcasecmp (head->hname, "diversion")) { i = osip_header_clone (head, ©); if (i == 0) { osip_list_add (&msg->headers, copy, count); count++; } } pos++; } } } /* remove all previous authentication headers */ osip_list_special_free (&msg->authorizations, (void *(*)(void *)) &osip_authorization_free); osip_list_special_free (&msg->proxy_authorizations, (void *(*)(void *)) &osip_proxy_authorization_free); /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } i = eXosip_update_top_via (msg); if (i != 0) { osip_message_free (msg); return i; } if (out_tr->last_response->status_code == 401 || out_tr->last_response->status_code == 407) eXosip_add_authentication_information (msg, out_tr->last_response); else eXosip_add_authentication_information (msg, NULL); osip_message_force_update (msg); if (0 != osip_strcasecmp (msg->sip_method, "INVITE")) { i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, msg); } else { i = _eXosip_transaction_init (&tr, ICT, eXosip.j_osip, msg); } if (i != 0) { osip_message_free (msg); return i; } if (out_tr == jc->c_out_tr) { /* replace with the new tr */ osip_list_add (&eXosip.j_transactions, jc->c_out_tr, 0); jc->c_out_tr = tr; /* fix dialog issue */ if (jd != NULL) { REMOVE_ELEMENT (jc->c_dialogs, jd); eXosip_dialog_free (jd); jd = NULL; } } else { /* add the new tr for the current dialog */ osip_list_add (jd->d_out_trs, tr, 0); } sipevent = osip_new_outgoing_sipmessage (msg); #ifndef MINISIZE osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd, NULL, NULL)); #else osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd)); #endif osip_transaction_add_event (tr, sipevent); eXosip_update (); /* fixed? */ __eXosip_wakeup (); return OSIP_SUCCESS; }
int eXosip_call_send_ack (int did, osip_message_t * ack) { eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; int i; osip_route_t *route; char *host; int port; if (did <= 0) return OSIP_BADPARAMETER; if (did > 0) { eXosip_call_dialog_find (did, &jc, &jd); } if (jc == NULL || jd == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); if (ack != NULL) osip_message_free (ack); return OSIP_NOTFOUND; } if (ack == NULL) { i = eXosip_call_build_ack (did, &ack); if (i != 0) { return i; } } osip_message_get_route (ack, 0, &route); if (route != NULL) { osip_uri_param_t *lr_param = NULL; osip_uri_uparam_get_byname (route->url, "lr", &lr_param); if (lr_param == NULL) route = NULL; } if (route != NULL) { port = 5060; if (route->url->port != NULL) port = osip_atoi (route->url->port); host = route->url->host; } else { /* search for maddr parameter */ osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname (ack->req_uri, "maddr", &maddr_param); host = NULL; if (maddr_param != NULL && maddr_param->gvalue != NULL) host = maddr_param->gvalue; port = 5060; if (ack->req_uri->port != NULL) port = osip_atoi (ack->req_uri->port); if (host == NULL) host = ack->req_uri->host; } i = cb_snd_message (NULL, ack, host, port, -1); if (jd->d_ack != NULL) osip_message_free (jd->d_ack); jd->d_ack = ack; if (i < 0) return i; /* TODO: could be 1 for icmp... */ return OSIP_SUCCESS; }
void ict_rcv_3456xx(osip_transaction_t * ict, osip_event_t * evt) { osip_route_t *route; int i; osip_t *osip = (osip_t *) ict->config; /* leave this answer to the core application */ if (ict->last_response != NULL) osip_message_free(ict->last_response); ict->last_response = evt->sip; if (ict->state != ICT_COMPLETED) { /* not a retransmission */ /* automatic handling of ack! */ osip_message_t *ack = ict_create_ack(ict, evt->sip); ict->ack = ack; if (ict->ack == NULL) { __osip_transaction_set_state(ict, ICT_TERMINATED); __osip_kill_transaction_callback(OSIP_ICT_KILL_TRANSACTION, ict); return; } /* reset ict->ict_context->destination only if it is not yet set. */ if (ict->ict_context->destination == NULL) { osip_message_get_route(ack, 0, &route); if (route != NULL && route->url != NULL) { osip_uri_param_t *lr_param; osip_uri_uparam_get_byname(route->url, "lr", &lr_param); if (lr_param == NULL) { /* using uncompliant proxy: destination is the request-uri */ route = NULL; } } if (route != NULL && route->url != NULL) { int port = 5060; if (route->url->port != NULL) port = osip_atoi(route->url->port); osip_ict_set_destination(ict->ict_context, osip_strdup(route->url->host), port); } else { int port = 5060; /* search for maddr parameter */ osip_uri_param_t *maddr_param = NULL; port = 5060; if (ack->req_uri->port != NULL) port = osip_atoi(ack->req_uri->port); osip_uri_uparam_get_byname(ack->req_uri, "maddr", &maddr_param); if (maddr_param != NULL && maddr_param->gvalue != NULL) osip_ict_set_destination(ict->ict_context, osip_strdup(maddr_param->gvalue), port); else osip_ict_set_destination(ict->ict_context, osip_strdup(ack->req_uri->host), port); } } i = osip->cb_send_message(ict, ack, ict->ict_context->destination, ict->ict_context->port, ict->out_socket); if (i != 0) { ict_handle_transport_error(ict, i); return; } if (MSG_IS_STATUS_3XX(evt->sip)) __osip_message_callback(OSIP_ICT_STATUS_3XX_RECEIVED, ict, evt->sip); else if (MSG_IS_STATUS_4XX(evt->sip)) __osip_message_callback(OSIP_ICT_STATUS_4XX_RECEIVED, ict, evt->sip); else if (MSG_IS_STATUS_5XX(evt->sip)) __osip_message_callback(OSIP_ICT_STATUS_5XX_RECEIVED, ict, evt->sip); else __osip_message_callback(OSIP_ICT_STATUS_6XX_RECEIVED, ict, evt->sip); __osip_message_callback(OSIP_ICT_ACK_SENT, ict, evt->sip); } /* start timer D (length is set to MAX (64*DEFAULT_T1 or 32000) */ osip_gettimeofday(&ict->ict_context->timer_d_start, NULL); add_gettimeofday(&ict->ict_context->timer_d_start, ict->ict_context->timer_d_length); __osip_transaction_set_state(ict, ICT_COMPLETED); }
int __osip_nict_init (osip_nict_t ** nict, osip_t * osip, osip_message_t * request) { osip_route_t *route; int i; time_t now; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "allocating NICT context\n")); *nict = (osip_nict_t *) osip_malloc (sizeof (osip_nict_t)); if (*nict == NULL) return -1; now = time (NULL); #ifndef DISABLE_MEMSET memset (*nict, 0, sizeof (osip_nict_t)); #else (*ict)->destination = NULL; #endif /* for REQUEST retransmissions */ { osip_via_t *via; char *proto; i = osip_message_get_via (request, 0, &via); /* get top via */ if (i != 0) goto ii_error_1; proto = via_get_protocol (via); if (proto == NULL) goto ii_error_1; i = osip_strncasecmp (proto, "TCP", 3); if (i != 0) { /* for other reliable protocol than TCP, the timer must be desactived by the external application */ (*nict)->timer_e_length = DEFAULT_T1; (*nict)->timer_e_start = now; /* started */ (*nict)->timer_k_length = DEFAULT_T4; (*nict)->timer_k_start = -1; /* not started */ } else { /* TCP is used: */ (*nict)->timer_e_length = -1; /* E is not ACTIVE */ (*nict)->timer_e_start = -1; (*nict)->timer_k_length = 0; /* MUST do the transition immediatly */ (*nict)->timer_k_start = -1; /* not started */ } } /* for PROXY, the destination MUST be set by the application layer, this one may not be correct. */ osip_message_get_route (request, 0, &route); if (route != NULL) { int port = 5060; if (route->url->port != NULL) port = osip_atoi (route->url->port); osip_nict_set_destination ((*nict), osip_strdup (route->url->host), port); } else (*nict)->port = 5060; (*nict)->timer_f_length = 64 * DEFAULT_T1; (*nict)->timer_f_start = now; /* started */ /* Oups! a Bug! */ /* (*nict)->port = 5060; */ return 0; ii_error_1: osip_free (*nict); return -1; }
/* This method returns: -2 if plugin consider this request should be totally discarded! -1 on error 0 nothing has been done 1 things has been done on psp_req element */ int cb_ls_localdb_search_user_location (psp_request_t * psp_req) { osip_route_t *route; ppl_uinfo_t *uinfo; int i; int numlocs = 0 /* DAB */ ; osip_message_t *request; request = psp_request_get_request(psp_req); /* default OUTPUT */ if (ISSET_R_ROUTE_MODE (ls_localdb_context->flag)) psp_request_set_property (psp_req, PSP_STAY_ON_PATH); else psp_request_set_property (psp_req, 0); /* mode */ if (ISSET_FORKING_MODE (ls_localdb_context->flag)) psp_request_set_mode (psp_req, PSP_FORK_MODE); else if (ISSET_SEQUENTIAL_MODE (ls_localdb_context->flag)) psp_request_set_mode (psp_req, PSP_SEQ_MODE); else if (ISSET_REDIRECT_MODE (ls_localdb_context->flag)) { psp_request_set_uas_status (psp_req, 302); psp_request_set_mode (psp_req, PSP_UAS_MODE); } else psp_request_set_mode (psp_req, PSP_FORK_MODE); psp_request_set_state (psp_req, PSP_MANDATE); /* THIS IS MANDATORY FOR ALL PLUGINS TO CHECK THAT! this is rarely used as a previous plugin 'ls_localdb' should have checked for it. In case you remove it. */ osip_message_get_route (request, 1, &route); if (route != NULL) { if (ISSET_SEQUENTIAL_MODE (ls_localdb_context->flag)) psp_request_set_mode (psp_req, PSP_SEQ_MODE); else psp_request_set_mode (psp_req, PSP_FORK_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return 0; /* do nothing.. */ } if (request->req_uri->username == NULL) { /* Propose 484, but let's keep searching if another plugin can find the destination. */ psp_request_set_uas_status (psp_req, 484); psp_request_set_state (psp_req, PSP_CONTINUE); psp_request_set_mode (psp_req, PSP_UAS_MODE); return 0; } /* look for this URI in our list of users */ uinfo = ppl_uinfo_find_by_aor (request->req_uri); if (uinfo != NULL) { /* add all locations to the psp_req element */ binding_t *bind; binding_t *bindnext; location_t *loc; osip_uri_t *url; bind = uinfo->bindings; bindnext = uinfo->bindings; for (; bind != NULL; bind = bindnext) { bindnext = bind->next; i = ppl_uinfo_check_binding (bind); if (i != 0) { /* binding is expired */ ppl_uinfo_remove_binding (uinfo, bind); } } bind = uinfo->bindings; if (bind == NULL) { /* user is not around... */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ls_localdb plugin: User Exist but has no valid registration!\n")); psp_request_set_uas_status (psp_req, 480); psp_request_set_mode (psp_req, PSP_UAS_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return 0; } bindnext = uinfo->bindings; /* DAB */ for (; bind != NULL; bind = bindnext) /* DAB */ { /* DAB */ /* If this is an INVITE Request, collect all locations DAB */ #ifdef EXPERIMENTAL_FORK if (MSG_IS_INVITE (request)) bindnext = bind->next; /* DAB */ else bindnext = NULL; /* DAB */ #else /* always accept only ONE location even for INVITE */ /* this is a limitation for stability reason as the forking mode is unfinished (calculation of the best response is not compliant to the rfc3261.txt behavior. */ bindnext = NULL; /* loop will be execute onece only */ #endif i = osip_uri_clone (bind->contact->url, &url); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ls_localdb plugin: Could not clone contact info!\n")); psp_request_set_uas_status (psp_req, 400); psp_request_set_mode (psp_req, PSP_UAS_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return -1; } i = location_init (&loc, url, 3600); if (i != 0) { osip_uri_free (url); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_BUG, NULL, "ls_localdb plugin: Could not create location info!\n")); psp_request_set_uas_status (psp_req, 400); psp_request_set_mode (psp_req, PSP_UAS_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return -1; } /* new support for rfc3327.txt and Path header */ if (bind->path!=NULL) location_set_path(loc, osip_strdup(bind->path)); ADD_ELEMENT (psp_req->locations, loc); numlocs++; /* DAB */ } /* DAB */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ls_localdb plugin: %d locations found!\n", numlocs)); return 0; } /* no user location found in local database... */ psp_request_set_uas_status (psp_req, 404); psp_request_set_state (psp_req, PSP_CONTINUE); psp_request_set_mode (psp_req, PSP_UAS_MODE); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ls_localdb plugin: No location found for known user: return 404 Not found!!\n")); return 0; }
static int udp_tl_send_message(osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket) { int len = 0; size_t length = 0; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; char *message = NULL; char ipbuf[INET6_ADDRSTRLEN]; int i; osip_naptr_t *naptr_record=NULL; if (udp_socket <= 0) return -1; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi(sip->req_uri->port); else port = 5060; } eXtl_update_local_target(sip); i = -1; #ifndef MINISIZE if (tr==NULL) { _eXosip_srv_lookup(sip, &naptr_record); if (naptr_record!=NULL) { eXosip_dnsutils_dns_process(naptr_record, 1); if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NAPTRDONE ||naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVINPROGRESS) eXosip_dnsutils_dns_process(naptr_record, 1); } if (naptr_record!=NULL && naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVDONE) { /* 4: check if we have the one we want... */ if (naptr_record->sipudp_record.name[0] != '\0' && naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0] != '\0') { /* always choose the first here. if a network error occur, remove first entry and replace with next entries. */ osip_srv_entry_t *srv; int n = 0; for (srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index]; n < 10 && naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0]; srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index]) { if (srv->ipaddress[0]) i = eXosip_get_addrinfo(&addrinfo, srv->ipaddress, srv->port, IPPROTO_UDP); else i = eXosip_get_addrinfo(&addrinfo, srv->srv, srv->port, IPPROTO_UDP); if (i == 0) { host = srv->srv; port = srv->port; break; } i = eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record); if (i<=0) { return -1; } if (i>=n) { return -1; } i = -1; /* copy next element */ n++; } } } if (naptr_record!=NULL && naptr_record->keep_in_cache==0) osip_free(naptr_record); naptr_record=NULL; } else { naptr_record = tr->naptr_record; } if (naptr_record!=NULL) { /* 1: make sure there is no pending DNS */ eXosip_dnsutils_dns_process(naptr_record, 0); if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NAPTRDONE ||naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVINPROGRESS) eXosip_dnsutils_dns_process(naptr_record, 0); if (naptr_record->naptr_state==OSIP_NAPTR_STATE_UNKNOWN) { /* fallback to DNS A */ if (naptr_record->keep_in_cache==0) osip_free(naptr_record); naptr_record=NULL; if (tr!=NULL) tr->naptr_record=NULL; /* must never happen? */ } else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_INPROGRESS) { /* 2: keep waiting (naptr answer not received) */ return OSIP_SUCCESS + 1; } else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NAPTRDONE) { /* 3: keep waiting (naptr answer received/no srv answer received) */ return OSIP_SUCCESS + 1; } else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVINPROGRESS) { /* 3: keep waiting (naptr answer received/no srv answer received) */ return OSIP_SUCCESS + 1; } else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVDONE) { /* 4: check if we have the one we want... */ if (naptr_record->sipudp_record.name[0] != '\0' && naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0] != '\0') { /* always choose the first here. if a network error occur, remove first entry and replace with next entries. */ osip_srv_entry_t *srv; int n = 0; for (srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index]; n < 10 && naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0]; srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index]) { if (srv->ipaddress[0]) i = eXosip_get_addrinfo(&addrinfo, srv->ipaddress, srv->port, IPPROTO_UDP); else i = eXosip_get_addrinfo(&addrinfo, srv->srv, srv->port, IPPROTO_UDP); if (i == 0) { host = srv->srv; port = srv->port; break; } i = eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record); if (i<=0) { return -1; } if (i>=n) { return -1; } i = -1; /* copy next element */ n++; } } } else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NOTSUPPORTED ||naptr_record->naptr_state==OSIP_NAPTR_STATE_RETRYLATER) { /* 5: fallback to DNS A */ if (naptr_record->keep_in_cache==0) osip_free(naptr_record); naptr_record=NULL; if (tr!=NULL) tr->naptr_record=NULL; } } #endif /* if SRV was used, destination may be already found */ if (i != 0) { i = eXosip_get_addrinfo(&addrinfo, host, port, IPPROTO_UDP); } if (i != 0) { return -1; } memcpy(&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); len = addrinfo->ai_addrlen; eXosip_freeaddrinfo(addrinfo); /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route = NULL; osip_generic_param_t *tag = NULL; osip_message_get_route(sip, 0, &route); osip_to_get_tag(sip->to, &tag); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_remove(&sip->routes, 0); } i = osip_message_to_str(sip, &message, &length); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_add(&sip->routes, route, 0); } } if (i != 0 || length <= 0) { osip_free(message); return -1; } switch (((struct sockaddr *) &addr)->sa_family) { case AF_INET: inet_ntop(((struct sockaddr *) &addr)->sa_family, &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf, sizeof(ipbuf)); break; case AF_INET6: inet_ntop(((struct sockaddr *) &addr)->sa_family, &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf, sizeof(ipbuf)); break; default: strncpy(ipbuf, "(unknown)", sizeof(ipbuf)); break; } OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: (to dest=%s:%i)\n%s\n", ipbuf, port, message)); if (osip_strcasecmp(host, ipbuf)!=0 && MSG_IS_REQUEST(sip)) { if (MSG_IS_REGISTER(sip)) { struct eXosip_dns_cache entry; memset(&entry, 0, sizeof(struct eXosip_dns_cache)); snprintf(entry.host, sizeof(entry.host), "%s", host); snprintf(entry.ip, sizeof(entry.ip), "%s", ipbuf); eXosip_set_option(EXOSIP_OPT_ADD_DNS_CACHE, (void *) &entry); } } if (tr != NULL) { if (tr->ict_context != NULL) osip_ict_set_destination(tr->ict_context, osip_strdup(ipbuf), port); if (tr->nict_context != NULL) osip_nict_set_destination(tr->nict_context, osip_strdup(ipbuf), port); } if (0 > sendto(udp_socket, (const void *) message, length, 0, (struct sockaddr *) &addr, len)) { #ifndef MINISIZE if (naptr_record!=NULL) { /* rotate on failure! */ if (eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record)>0) { osip_free(message); return OSIP_SUCCESS + 1; /* retry for next retransmission! */ } } #endif /* SIP_NETWORK_ERROR; */ osip_free(message); return -1; } if (eXosip.keep_alive > 0) { if (MSG_IS_REGISTER(sip)) { eXosip_reg_t *reg = NULL; if (_eXosip_reg_find(®, tr) == 0) { memcpy(&(reg->addr), &addr, len); reg->len = len; } } } #ifndef MINISIZE if (naptr_record!=NULL) { if (tr!=NULL && MSG_IS_REGISTER(sip) && tr->last_response==NULL) { /* failover for outgoing transaction */ time_t now; now = time(NULL); OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "not yet answered\n")); if (tr != NULL && now - tr->birth_time > 10 && now - tr->birth_time < 13) { /* avoid doing this twice... */ if (eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record)>0) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "Doing failover: %s:%i->%s:%i\n", host, port, naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv, naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].port)); osip_free(message); return OSIP_SUCCESS + 1; /* retry for next retransmission! */ } } } } #endif osip_free(message); return OSIP_SUCCESS; }
static int dtls_tl_send_message(osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket) { int len = 0; size_t length = 0; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; char *message; char ipbuf[INET6_ADDRSTRLEN]; int i; int pos; struct socket_tab *socket_tab_used=NULL; BIO *sbio=NULL; if (dtls_socket <= 0) return -1; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5061; } if (port == 5060) port = 5061; if (MSG_IS_REQUEST(sip)) { if (MSG_IS_REGISTER(sip) ||MSG_IS_INVITE(sip) ||MSG_IS_SUBSCRIBE(sip) || MSG_IS_NOTIFY(sip)) eXtl_update_local_target(sip); } i=-1; #ifndef MINISIZE if (tr!=NULL && tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0') { /* always choose the first here. if a network error occur, remove first entry and replace with next entries. */ osip_srv_entry_t *srv; int n=0; for (srv = &tr->record.srventry[0]; n<10 && tr->record.srventry[0].srv[0]; srv = &tr->record.srventry[0]) { i = eXosip_get_addrinfo (&addrinfo, srv->srv, srv->port, IPPROTO_UDP); if (i == 0) { host = srv->srv; port = srv->port; break; } memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t)); memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t)); i=-1; /* copy next element */ n++; } } #endif /* if SRV was used, distination may be already found */ if (i != 0) { i = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_UDP); } if (i != 0) { return -1; } memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); len = addrinfo->ai_addrlen; eXosip_freeaddrinfo (addrinfo); /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route=NULL; osip_generic_param_t *tag=NULL; osip_message_get_route (sip, 0, &route); osip_to_get_tag (sip->to, &tag); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_remove(&sip->routes, 0); } i = osip_message_to_str (sip, &message, &length); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_add(&sip->routes, route, 0); } } if (i != 0 || length <= 0) { return -1; } switch ( ((struct sockaddr *)&addr)->sa_family ) { case AF_INET: inet_ntop (((struct sockaddr *)&addr)->sa_family, &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf, sizeof (ipbuf)); break; case AF_INET6: inet_ntop (((struct sockaddr *)&addr)->sa_family, &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf, sizeof (ipbuf)); break; default: strncpy (ipbuf, "(unknown)", sizeof (ipbuf)); break; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (to dest=%s:%i)\n", message, ipbuf, port)); for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (dtls_socket_tab[pos].ssl_conn != NULL && dtls_socket_tab[pos].ssl_type == EXOSIP_AS_A_SERVER) { if (dtls_socket_tab[pos].remote_port == port && (strcmp (dtls_socket_tab[pos].remote_ip, ipbuf) == 0)) { BIO *rbio; socket_tab_used = &dtls_socket_tab[pos]; rbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE); BIO_dgram_set_peer (rbio, &addr); dtls_socket_tab[pos].ssl_conn->rbio = rbio; break; } } } if (socket_tab_used==NULL) { for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (dtls_socket_tab[pos].ssl_conn != NULL && dtls_socket_tab[pos].ssl_type == EXOSIP_AS_A_CLIENT) { if (dtls_socket_tab[pos].remote_port == port && (strcmp (dtls_socket_tab[pos].remote_ip, ipbuf) == 0)) { BIO *rbio; socket_tab_used = &dtls_socket_tab[pos]; rbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE); BIO_dgram_set_peer (rbio, &addr); dtls_socket_tab[pos].ssl_conn->rbio = rbio; break; } } } } if (socket_tab_used==NULL) { /* delete an old one! */ pos=0; if (dtls_socket_tab[pos].ssl_conn != NULL) { shutdown_free_client_dtls (pos); shutdown_free_server_dtls (pos); } memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab)); } if (dtls_socket_tab[pos].ssl_conn == NULL) { /* create a new one */ SSL_CTX_set_read_ahead (client_ctx, 1); dtls_socket_tab[pos].ssl_conn = SSL_new (client_ctx); if (dtls_socket_tab[pos].ssl_conn == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "DTLS SSL_new error\n")); if (dtls_socket_tab[pos].ssl_conn != NULL) { shutdown_free_client_dtls (pos); shutdown_free_server_dtls (pos); } memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab)); osip_free (message); return -1; } if (connect (dtls_socket, (struct sockaddr *) &addr, sizeof (addr)) == -1) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "DTLS connect error\n")); if (dtls_socket_tab[pos].ssl_conn != NULL) { shutdown_free_client_dtls (pos); shutdown_free_server_dtls (pos); } memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab)); osip_free (message); return -1; } SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_NO_QUERY_MTU); SSL_set_mtu (dtls_socket_tab[pos].ssl_conn, 2000); SSL_set_connect_state (dtls_socket_tab[pos].ssl_conn); sbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE); BIO_ctrl_set_connected (sbio, 1, (struct sockaddr *) &addr); SSL_set_bio (dtls_socket_tab[pos].ssl_conn, sbio, sbio); dtls_socket_tab[pos].ssl_type = 2; dtls_socket_tab[pos].ssl_state = 2; osip_strncpy (dtls_socket_tab[pos].remote_ip, ipbuf, sizeof (dtls_socket_tab[pos].remote_ip)); dtls_socket_tab[pos].remote_port = port; } i = SSL_write (dtls_socket_tab[pos].ssl_conn, message, length); if (i<0) { i = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i); print_ssl_error (i); if (i==SSL_ERROR_SSL || i==SSL_ERROR_SYSCALL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "DTLS SSL_write error\n")); if (dtls_socket_tab[pos].ssl_conn != NULL) { shutdown_free_client_dtls (pos); shutdown_free_server_dtls (pos); } memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab)); } #ifndef MINISIZE /* delete first SRV entry that is not reachable */ if (tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0') { memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t)); memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t)); osip_free (message); return 0; /* retry for next retransmission! */ } #endif /* SIP_NETWORK_ERROR; */ osip_free (message); return -1; } if (eXosip.keep_alive > 0) { if (MSG_IS_REGISTER (sip)) { eXosip_reg_t *reg = NULL; if (_eXosip_reg_find (®, tr) == 0) { memcpy (&(reg->addr), &addr, len); reg->len = len; } } } osip_free (message); return 0; }
/* This method returns: -2 if plugin consider this request should be totally discarded! -1 on error 0 nothing has been done 1 things has been done on psp_req element */ int cb_groups_search_location(psp_request_t *psp_req) { location_t *loc; osip_route_t *route; int i; int index; int match; grp_t *grp=NULL; osip_uri_param_t *psp_param; osip_message_t *request; request = psp_request_get_request(psp_req); OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "groups plugin: entering cb_groups_search_location\n")); /* default OUTPUT */ if (ISSET_R_ROUTE_MODE(groups_context->flag)) psp_request_set_property(psp_req, PSP_STAY_ON_PATH); else psp_request_set_property(psp_req, 0); psp_request_set_mode(psp_req, PSP_SFULL_MODE); i=0; for (; !osip_list_eol(&request->routes, i); i++) { osip_message_get_route (request, i, &route); if (0 != psp_core_is_responsible_for_this_route(route->url)) { psp_request_set_mode (psp_req, PSP_SFULL_MODE); psp_request_set_state (psp_req, PSP_MANDATE); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "groups plugin: mandate statefull handling for route.\n")); return 0; } } psp_request_set_state(psp_req, PSP_MANDATE); if (i>1) { psp_request_set_uas_status(psp_req, 482); /* loop? */ psp_request_set_mode(psp_req, PSP_UAS_MODE); return 0; } if (i==1) { osip_message_get_route(request, 0, &route); /* should be the first one */ /* if this route header contains the "psp" parameter, it means the element does not come from a pre-route-set header (in this last case, we want to execute the plugin for the initial request) */ /* NON compliant UAs (not returning this parameter) are guilty. */ osip_uri_uparam_get_byname (route->url, "psp", &psp_param); if (psp_param!=NULL) { psp_request_set_state(psp_req, PSP_MANDATE); psp_request_set_mode (psp_req, PSP_SFULL_MODE); /* got it, leave this plugin. */ return 0; } } if (request->req_uri->username==NULL || request->req_uri->host==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "groups plugin: No username in uri.\n")); psp_request_set_state(psp_req, PSP_PROPOSE); psp_request_set_uas_status(psp_req, 404); psp_request_set_mode(psp_req, PSP_UAS_MODE); return 0; } /* search for a group */ match=0; for (index=0; index<MAX_GROUPS; index++) { grp = &(groups_context->grps[index]); if (grp->group[0]!='\0') { if (osip_strcasecmp(grp->group, request->req_uri->username)==0) { if (grp->domain[0]=='\0') { match=1; break; } else if (osip_strcasecmp(grp->domain, request->req_uri->host)==0) { match=1; break; } } } grp=NULL; } if (match==1 && grp!=NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "groups plugin: A group match this call (%s).\n", grp->group)); for (index=0; index<MAX_MEMBERS; index++) { osip_uri_t *uri; int i; char *dest; dest = grp->members[index]; if (dest[0]=='\0') break; OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO3,NULL, "groups plugin: members of %s: %s\n", grp->group, dest)); osip_uri_init(&uri); i = osip_uri_parse(uri, dest); if (i==0) { i = location_init(&loc, uri, 3600); if (i!=0) { /* This can only happen in case we don't have enough memory */ osip_uri_free(uri); OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL, "groups plugin: Could not create location info!\n")); } else { ADD_ELEMENT(psp_req->locations, loc); } } } return 0; } OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "groups plugin: Didn't do anything with this request?\n")); psp_request_set_state(psp_req, PSP_PROPOSE); psp_request_set_uas_status(psp_req, 404); psp_request_set_mode(psp_req, PSP_UAS_MODE); return 0; }
int _eXosip_srv_lookup(osip_transaction_t * tr, osip_message_t * sip, struct osip_srv_record *record) { int use_srv = 1; int port; char *host; osip_via_t *via; via = (osip_via_t *) osip_list_get(&sip->vias, 0); if (via == NULL || via->protocol == NULL) return OSIP_BADPARAMETER; if (MSG_IS_REQUEST(sip)) { osip_route_t *route; osip_message_get_route(sip, 0, &route); if (route != NULL) { osip_uri_param_t *lr_param = NULL; osip_uri_uparam_get_byname(route->url, "lr", &lr_param); if (lr_param == NULL) route = NULL; } if (route != NULL) { port = 5060; if (route->url->port != NULL) { port = osip_atoi(route->url->port); use_srv = 0; } host = route->url->host; } else { /* search for maddr parameter */ osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname(sip->req_uri, "maddr", &maddr_param); host = NULL; if (maddr_param != NULL && maddr_param->gvalue != NULL) host = maddr_param->gvalue; port = 5060; if (sip->req_uri->port != NULL) { use_srv = 0; port = osip_atoi(sip->req_uri->port); } if (host == NULL) host = sip->req_uri->host; } } else { osip_generic_param_t *maddr; osip_generic_param_t *received; osip_generic_param_t *rport; osip_via_param_get_byname(via, "maddr", &maddr); osip_via_param_get_byname(via, "received", &received); osip_via_param_get_byname(via, "rport", &rport); if (maddr != NULL) host = maddr->gvalue; else if (received != NULL) host = received->gvalue; else host = via->host; if (via->port == NULL) use_srv = 0; if (rport == NULL || rport->gvalue == NULL) { if (via->port != NULL) port = osip_atoi(via->port); else port = 5060; } else port = osip_atoi(rport->gvalue); } if (host == NULL) { return OSIP_UNKNOWN_HOST; } /* check if we have an IPv4 or IPv6 address */ if (strchr(host, ':') || (INADDR_NONE != inet_addr(host))) { return OSIP_UNKNOWN_HOST; } if (use_srv == 1) { int i; i = eXosip_get_srv_record(record, host, via->protocol); return i; } return OSIP_SUCCESS; }