Exemple #1
0
void linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route)
{
	int err;
	osip_uri_param_t *lr_param=NULL;
	osip_route_t *rt=NULL;
	char *tmproute=NULL;
	if (route!=NULL && strlen(route)>0){
		osip_route_init(&rt);
		err=osip_route_parse(rt,route);
		if (err<0){
			ms_warning("Could not parse %s",route);
			osip_route_free(rt);
			return ;
		}
		if (obj->reg_route!=NULL) {
			ms_free(obj->reg_route);
			obj->reg_route=NULL;
		}
			
		/* check if the lr parameter is set , if not add it */
		osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
	  	if (lr_param==NULL){
			osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
			osip_route_to_str(rt,&tmproute);
			obj->reg_route=ms_strdup(tmproute);
			osip_free(tmproute);
		}else obj->reg_route=ms_strdup(route);
	}else{
		if (obj->reg_route!=NULL) ms_free(obj->reg_route);
		obj->reg_route=NULL;
	}
}
Exemple #2
0
/* Set loose route if not set in route url */
char* uas_check_route(const char *url)
{
	int err;
	osip_uri_param_t *lr_param=NULL;
	osip_route_t *rt=NULL;
	char *route=NULL;
   
	if (url!=NULL && strlen(url)>0)
   {
		osip_route_init(&rt);
		err=osip_route_parse(rt,url);
		if (err<0)
      {
			osip_route_free(rt);



			return NULL;
		}

      /* check if the lr parameter is set , if not add it */
		osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
	  	if (lr_param==NULL)
      {
			osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);

			osip_route_to_str(rt,&route);
         
         return route;
		}

      return xstr_clone(url);
	}

   return NULL;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
int CIctTransaction::CIct::Init(CSipMessage* invite)
{
	CRoute* route;
	int i;
	time_t now;

	now = time(NULL);
	/* for INVITE retransmissions */
	{
		CVia* via;
		char* proto;

		i = invite->GetVia(0,&via); /* get top via */
		if (i != 0 || via == NULL)
		{
			return -1;
		}
		proto = via->m_pcProtocol;
		if (proto == NULL)
		{
			return -1;
		}

		if (zstr_strcasecmp(proto, "TCP") != 0 && zstr_strcasecmp(proto, "TLS") != 0 &&	zstr_strcasecmp(proto,"SCTP") != 0)
		{
			/* for other reliable protocol than TCP, the timer
					   must be desactived by the external application */
			if (64 * DEFAULT_T1 < 32000)
				m_TimerD.SetTimer(32000,false);
			else
				m_TimerD.SetTimer(64 * DEFAULT_T1,false);

			m_TimerA.SetTimer(DEFAULT_T1,true);
		}
		else
		{
			/* reliable protocol is used: */
			m_TimerA.ReSetTimer();
			m_TimerD.ReSetTimer();
		}
	}

	/* for PROXY, the destination MUST be set by the application layer,
	   this one may not be correct. */
	invite->GetRoute(0,&route);
	if (route != NULL && route->url != NULL)
	{
		CUrlParam* 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)
	{
		int port = 5060;

		if (route->url->port != NULL)
			port = zstr_atoi(route->url->port);
		this->SetDestination(zstr_strdup(route->url->host), port);
	}
	else
	{
		int port = 5060;
		/* search for maddr parameter */
		CUrlParam* maddr_param = NULL;

		port = 5060;
		if (invite->m_pRequestUrl->port != NULL)
		{
			port = zstr_atoi(invite->m_pRequestUrl->port);
		}

		osip_uri_uparam_get_byname(invite->m_pRequestUrl, "maddr", &maddr_param);
		if (maddr_param != NULL && maddr_param->gvalue != NULL)
		{
			this->SetDestination(zstr_strdup(maddr_param->gvalue),port);
		}
		else
		{
			this->SetDestination(zstr_strdup(invite->m_pRequestUrl->host), port);
		}
	}
	
	m_TimerB.SetTimer(64 * DEFAULT_T1,true);
	/* Oups! A bug! */
	/*  ict_context->port  = 5060; */

	return 0;
}
Exemple #4
0
static int
dialog_fill_route_set (osip_dialog_t * dialog, osip_message_t * request)
{
  /* if the pre-existing route set contains a "lr" (compliance
     with bis-08) then the req_uri should contains the remote target
     URI */
  int i;
  int pos = 0;
  osip_uri_param_t *lr_param;
  osip_route_t *route;
  char *last_route;

  /* AMD bug: fixed 17/06/2002 */

  route = (osip_route_t *) osip_list_get (&dialog->route_set, 0);

  osip_uri_uparam_get_byname (route->url, "lr", &lr_param);
  if (lr_param != NULL)         /* the remote target URI is the req_uri! */
    {
      i = osip_uri_clone (dialog->remote_contact_uri->url, &(request->req_uri));
      if (i != 0)
        return i;
      /* "[request] MUST includes a Route header field containing
         the route set values in order." */
      /* AMD bug: fixed 17/06/2002 */
      pos = 0;                  /* first element is at index 0 */
      while (!osip_list_eol (&dialog->route_set, pos))
        {
          osip_route_t *route2;

          route = osip_list_get (&dialog->route_set, pos);
          i = osip_route_clone (route, &route2);
          if (i != 0)
            return i;
          osip_list_add (&request->routes, route2, -1);
          pos++;
        }
      return OSIP_SUCCESS;
    }

  /* if the first URI of route set does not contain "lr", the req_uri
     is set to the first uri of route set */


  i = osip_uri_clone (route->url, &(request->req_uri));
  if (i != 0)
    return i;
  /* add the route set */
  /* "The UAC MUST add a route header field containing
     the remainder of the route set values in order. */
  pos = 0;                      /* yes it is */

  while (!osip_list_eol (&dialog->route_set, pos))      /* not the first one in the list */
    {
      osip_route_t *route2;

      route = osip_list_get (&dialog->route_set, pos);
      i = osip_route_clone (route, &route2);
      if (i != 0)
        return i;
      if (!osip_list_eol (&dialog->route_set, pos + 1))
        osip_list_add (&request->routes, route2, -1);
      else
        osip_route_free (route2);
      pos++;
    }

  /* The UAC MUST then place the remote target URI into
     the route header field as the last value */
  i = osip_uri_to_str (dialog->remote_contact_uri->url, &last_route);
  if (i != 0)
    return i;
  i = osip_message_set_route (request, last_route);
  osip_free (last_route);
  if (i != 0)
    {
      return i;
    }

  /* route header and req_uri set */
  return OSIP_SUCCESS;
}
Exemple #5
0
/* 
   method is the type of request. ("INVITE", "REGISTER"...)
   to is the remote target URI
   transport is either "TCP" or "UDP" (by now, only UDP is implemented!)
*/
int
generating_request_out_of_dialog (osip_message_t ** dest, const char *method,
                                  const char *to, const char *transport,
                                  const char *from, const char *proxy)
{
  /* Section 8.1:
     A valid request contains at a minimum "To, From, Call-iD, Cseq,
     Max-Forwards and Via
   */
  int i;
  osip_message_t *request;
  char locip[65];
  int doing_register;
  char *register_callid_number = NULL;

  *dest = NULL;

  if (eXosip.eXtl == NULL)
    return OSIP_NO_NETWORK;

  /*guess the local ip since req uri is known */
  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"));
      return OSIP_NO_NETWORK;
    }

  i = osip_message_init (&request);
  if (i != 0)
    return i;

  /* prepare the request-line */
  osip_message_set_method (request, osip_strdup (method));
  osip_message_set_version (request, osip_strdup ("SIP/2.0"));
  osip_message_set_status_code (request, 0);
  osip_message_set_reason_phrase (request, NULL);

  doing_register = 0 == strcmp ("REGISTER", method);

  if (doing_register)
    {
      osip_uri_init (&(request->req_uri));
      i = osip_uri_parse (request->req_uri, proxy);
      if (i != 0)
        {
          osip_message_free (request);
          return i;
        }
      i = osip_message_set_to (request, from);
      if (i != 0 || request->to == NULL)
        {
          if (i >= 0)
            i = OSIP_SYNTAXERROR;
          osip_message_free (request);
          return i;
        }
  } else
    {
      /* in any cases except REGISTER: */
      i = osip_message_set_to (request, to);
      if (i != 0 || request->to == NULL)
        {
          if (i >= 0)
            i = OSIP_SYNTAXERROR;
          OSIP_TRACE (osip_trace
                      (__FILE__, __LINE__, OSIP_ERROR, NULL,
                       "ERROR: callee address does not seems to be a sipurl: %s\n",
                       to));
          osip_message_free (request);
          return i;
        }

      /* REMOVE ALL URL PARAMETERS from to->url headers and add them as headers */
      if (request->to != NULL && request->to->url != NULL)
        {
          osip_uri_t *url = request->to->url;
          while (osip_list_size (&url->url_headers) > 0)
            {
              osip_uri_header_t *u_header;
              u_header = (osip_uri_param_t *) osip_list_get (&url->url_headers, 0);
              if (u_header == NULL)
                break;

              if (osip_strcasecmp (u_header->gname, "from") == 0)
                {
              } else if (osip_strcasecmp (u_header->gname, "to") == 0)
                {
              } else if (osip_strcasecmp (u_header->gname, "call-id") == 0)
                {
              } else if (osip_strcasecmp (u_header->gname, "cseq") == 0)
                {
              } else if (osip_strcasecmp (u_header->gname, "via") == 0)
                {
              } else if (osip_strcasecmp (u_header->gname, "contact") == 0)
                {
              } else
                osip_message_set_header (request, u_header->gname,
                                         u_header->gvalue);
              osip_list_remove (&url->url_headers, 0);
              osip_uri_param_free (u_header);
            }
        }

      if (proxy != NULL && proxy[0] != 0)
        {                       /* equal to a pre-existing route set */
          /* if the pre-existing route set contains a "lr" (compliance
             with bis-08) then the req_uri should contains the remote target
             URI */
          osip_uri_param_t *lr_param;
          osip_route_t *o_proxy;

          osip_route_init (&o_proxy);
          i = osip_route_parse (o_proxy, proxy);
          if (i != 0)
            {
              osip_route_free (o_proxy);
              osip_message_free (request);
              return i;
            }

          osip_uri_uparam_get_byname (o_proxy->url, "lr", &lr_param);
          if (lr_param != NULL) /* to is the remote target URI in this case! */
            {
              osip_uri_clone (request->to->url, &(request->req_uri));
              /* "[request] MUST includes a Route header field containing
                 the route set values in order." */
              osip_list_add (&request->routes, o_proxy, 0);
          } else
            /* if the first URI of route set does not contain "lr", the req_uri
               is set to the first uri of route set */
            {
              request->req_uri = o_proxy->url;
              o_proxy->url = NULL;
              osip_route_free (o_proxy);
              /* add the route set */
              /* "The UAC MUST add a route header field containing
                 the remainder of the route set values in order.
                 The UAC MUST then place the remote target URI into
                 the route header field as the last value
               */
              osip_message_set_route (request, to);
            }
      } else                    /* No route set (outbound proxy) is used */
        {
          /* The UAC must put the remote target URI (to field) in the req_uri */
          i = osip_uri_clone (request->to->url, &(request->req_uri));
          if (i != 0)
            {
              osip_message_free (request);
              return i;
            }
        }
    }

  /* set To and From */
  i = osip_message_set_from (request, from);
  if (i != 0 || request->from == NULL)
    {
      if (i >= 0)
        i = OSIP_SYNTAXERROR;
      osip_message_free (request);
      return i;
    }

  /* add a tag */
  osip_from_set_tag (request->from, osip_from_tag_new_random ());

  /* set the cseq and call_id header */
  {
    osip_call_id_t *callid;
    osip_cseq_t *cseq;
    char *num;
    char *cidrand;

    /* call-id is always the same for REGISTRATIONS */
    i = osip_call_id_init (&callid);
    if (i != 0)
      {
        osip_message_free (request);
        return i;
      }
    cidrand = osip_call_id_new_random ();
    osip_call_id_set_number (callid, cidrand);
    if (doing_register)
      register_callid_number = cidrand;

    request->call_id = callid;

    i = osip_cseq_init (&cseq);
    if (i != 0)
      {
        osip_message_free (request);
        return i;
      }
    num = osip_strdup (doing_register ? "1" : "20");
    osip_cseq_set_number (cseq, num);
    osip_cseq_set_method (cseq, osip_strdup (method));
    request->cseq = cseq;

    if (cseq->method == NULL || cseq->number == NULL)
      {
        osip_message_free (request);
        return OSIP_NOMEM;
      }
  }

  i = _eXosip_request_add_via (request, transport, locip);
  if (i != 0)
    {
      osip_message_free (request);
      return i;
    }

  /* always add the Max-Forward header */
  osip_message_set_max_forwards (request, "70");        /* a UA should start a request with 70 */

  if (0 == strcmp ("REGISTER", method))
    {
  } else if (0 == strcmp ("INFO", method))
    {
  } else if (0 == strcmp ("OPTIONS", method))
    {
      osip_message_set_accept (request, "application/sdp");
    }

  osip_message_set_user_agent (request, eXosip.user_agent);
  /*  else if ... */
  *dest = request;
  return OSIP_SUCCESS;
}
Exemple #6
0
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;
}
Exemple #7
0
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, &copy);
                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;
}
Exemple #8
0
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);
}
Exemple #9
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;

}
Exemple #10
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;
}