Exemple #1
0
void
_eXosip_dialog_free (struct eXosip_t *excontext, eXosip_dialog_t * jd)
{
  while (!osip_list_eol (jd->d_inc_trs, 0)) {
    osip_transaction_t *tr;

    tr = (osip_transaction_t *) osip_list_get (jd->d_inc_trs, 0);
    osip_list_remove (jd->d_inc_trs, 0);
    _eXosip_delete_reserved (tr);
    osip_list_add (&excontext->j_transactions, tr, 0);
  }

  while (!osip_list_eol (jd->d_out_trs, 0)) {
    osip_transaction_t *tr;

    tr = (osip_transaction_t *) osip_list_get (jd->d_out_trs, 0);
    osip_list_remove (jd->d_out_trs, 0);
    _eXosip_delete_reserved (tr);
    osip_list_add (&excontext->j_transactions, tr, 0);
  }

  osip_message_free (jd->d_200Ok);
  osip_message_free (jd->d_ack);

  osip_dialog_free (jd->d_dialog);

  osip_free (jd->d_out_trs);
  osip_free (jd->d_inc_trs);
  osip_free (jd);

  _eXosip_update (excontext);
}
void
eXosip_dialog_free (eXosip_dialog_t * jd)
{
  while (!osip_list_eol (jd->d_inc_trs, 0))
    {
      osip_transaction_t *tr;

      tr = (osip_transaction_t *) osip_list_get (jd->d_inc_trs, 0);
      osip_list_remove (jd->d_inc_trs, 0);
      __eXosip_delete_jinfo (tr);
      osip_list_add (eXosip.j_transactions, tr, 0);
    }

  while (!osip_list_eol (jd->d_out_trs, 0))
    {
      osip_transaction_t *tr;

      tr = (osip_transaction_t *) osip_list_get (jd->d_out_trs, 0);
      osip_list_remove (jd->d_out_trs, 0);
      __eXosip_delete_jinfo (tr);
      osip_list_add (eXosip.j_transactions, tr, 0);
    }

  osip_message_free (jd->d_200Ok);
  osip_message_free (jd->d_ack);

  osip_dialog_free (jd->d_dialog);

  osip_free (jd->d_out_trs);
  osip_free (jd->d_inc_trs);
  osip_free (jd);

  eXosip_update ();
}
int
sdp_message_a_attribute_del_at_index (sdp_message_t * sdp, int pos_media,
                                      char *att_field, int pos_attr)
{
  int i;
  sdp_media_t *med;
  sdp_attribute_t *attr;

  if (sdp == NULL)
    return -1;
  if ((pos_media != -1) && (osip_list_size (&sdp->m_medias) < pos_media + 1))
    return -1;
  if (pos_media == -1)
    {
      if (pos_attr == -1)
        {
          for (i = 0; i < osip_list_size (&sdp->a_attributes);)
            {
              attr = osip_list_get (&sdp->a_attributes, i);
              if (strcmp (attr->a_att_field, att_field) == 0)
                {
                  osip_list_remove (&sdp->a_attributes, i);
                  sdp_attribute_free (attr);
              } else
                i++;
            }
      } else if ((attr = osip_list_get (&sdp->a_attributes, pos_attr)) != NULL)
        {
          osip_list_remove (&sdp->a_attributes, pos_attr);
          sdp_attribute_free (attr);
        }
      return 0;
    }
  med = (sdp_media_t *) osip_list_get (&sdp->m_medias, pos_media);
  if (med == NULL)
    return -1;
  for (i = 0; i < osip_list_size (&med->a_attributes);)
    {
      if (pos_attr == -1)
        {
          attr = osip_list_get (&med->a_attributes, i);
          if (strcmp (attr->a_att_field, att_field) == 0)
            {
              osip_list_remove (&med->a_attributes, i);
              sdp_attribute_free (attr);
          } else
            i++;
      } else if ((attr = osip_list_get (&med->a_attributes, pos_attr)) != NULL)
        {
          osip_list_remove (&med->a_attributes, pos_attr);
          sdp_attribute_free (attr);
        }
    }
  return 0;
}
Exemple #4
0
int
eXosip_remove_transaction_from_call (osip_transaction_t * tr, eXosip_call_t * jc)
{
  osip_transaction_t *inc_tr;
  osip_transaction_t *out_tr;
  eXosip_dialog_t *jd;
  int pos = 0;

  if (jc->c_inc_tr == tr)
    {
      jc->c_inc_tr = NULL;      /* can be NULL */
      return 0;
    }

  for (jd = jc->c_dialogs; jd != NULL; jd = jd->next)
    {
      pos = 0;
      while (!osip_list_eol (jd->d_inc_trs, pos))
        {
          inc_tr = osip_list_get (jd->d_inc_trs, pos);
          if (inc_tr == tr)
            {
              osip_list_remove (jd->d_inc_trs, pos);
              return 0;
            }
          pos++;
        }
    }

  if (jc->c_out_tr == tr)
    {
      jc->c_out_tr = NULL;      /* can be NULL */
      return 0;
    }

  for (jd = jc->c_dialogs; jd != NULL; jd = jd->next)
    {
      pos = 0;
      while (!osip_list_eol (jd->d_out_trs, pos))
        {
          out_tr = osip_list_get (jd->d_out_trs, pos);
          if (out_tr == tr)
            {
              osip_list_remove (jd->d_out_trs, pos);
              return 0;
            }
          pos++;
        }
    }

  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
                          "eXosip: No information.\n"));
  return -1;
}
Exemple #5
0
static void GB_reset_Record_Node_list(GB_CONNECT_STATE *gb_cons)
{
	GB_Record_Node *record = NULL;
	osip_event_t *osip_event = NULL;

	while((record = (GB_Record_Node *)osip_list_get(&(gb_cons->record_node_list), 0)) != NULL)
	{
		if(record->cmd == 0 && record->call_id == NULL && record->data == NULL)
		{
			osip_event = (osip_event_t *)record->info;

			if(osip_event != NULL)
			{
				gb_sip_free(osip_event);
				osip_event = NULL;
			}
		}
		else
		{
			if(record->call_id)
				osip_call_id_free(record->call_id);
			if(record->data)
				SN_FREE(record->data);
			if(record->info)
				SN_FREE(record->info);
		}
		
		osip_list_remove(&(gb_cons->record_node_list), 0);
		SN_FREE(record);
		record = NULL;
	}
}
Exemple #6
0
static int
_eXosip_call_reuse_contact (osip_message_t * invite, osip_message_t * msg)
{
  osip_contact_t *co_invite = NULL;
  osip_contact_t *co_msg = NULL;
  int i;
  i = osip_message_get_contact (invite, 0, &co_invite);
  if (i < 0 || co_invite == NULL || co_invite->url == NULL)
    {
      return i;
    }

  i = osip_message_get_contact (msg, 0, &co_msg);
  if (i >= 0 && co_msg != NULL)
    {
      osip_list_remove (&msg->contacts, 0);
      osip_contact_free (co_msg);
    }

  co_msg = NULL;
  i = osip_contact_clone (co_invite, &co_msg);
  if (i >= 0 && co_msg != NULL)
    {
      osip_list_add (&msg->contacts, co_msg, 0);
      return OSIP_SUCCESS;
    }
  return i;
}
void
osip_uri_free (osip_uri_t * url)
{
  int pos = 0;

  if (url == NULL)
    return;
  osip_free (url->scheme);
  osip_free (url->username);
  osip_free (url->password);
  osip_free (url->host);
  osip_free (url->port);

  osip_uri_param_freelist (&url->url_params);

  {
    osip_uri_header_t *u_header;

    while (!osip_list_eol (&url->url_headers, pos))
      {
        u_header = (osip_uri_header_t *) osip_list_get (&url->url_headers, pos);
        osip_list_remove (&url->url_headers, pos);
        osip_uri_header_free (u_header);
      }
  }

  osip_free (url->string);

  osip_free (url);
}
Exemple #8
0
void *
osip_fifo_get (osip_fifo_t * ff)
{
  void *el;
  int i = osip_sem_wait (ff->qisempty);

  if (i != 0)
    return NULL;
  osip_mutex_lock (ff->qislocked);

  if (ff->etat != vide)
    {
      el = osip_list_get (ff->queue, 0);
      osip_list_remove (ff->queue, 0);
      /* ff->nb_elt--; */
    }
  else
    {
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
		   "no element in fifo.\n"));
      osip_mutex_unlock (ff->qislocked);
      return 0;			/* pile vide */
    }
  /* if (ff->nb_elt <= 0) */
  if (osip_list_size (ff->queue) <= 0)
    ff->etat = vide;
  else
    ff->etat = ok;

  osip_mutex_unlock (ff->qislocked);
  return el;
}
Exemple #9
0
int GB_Remove_Record_Node(GB_CONNECT_STATE *gb_cons, int index)
{
	GB_Record_Node *record = NULL;

	if(gb_cons == NULL)
	{
		TRACE(SCI_TRACE_NORMAL,MOD_GB,"%s  line=%d  Err\n",__FUNCTION__,__LINE__);
		return -1;
	}
	
	if(index <= osip_list_size(&(gb_cons->record_node_list)) && index >= 0)
	{
		record = (GB_Record_Node *)osip_list_get(&(gb_cons->record_node_list), index);

		if(record)
		{
			if(record->call_id)
				osip_call_id_free(record->call_id);
			if(record->data)
				SN_FREE(record->data);
			osip_list_remove(&(gb_cons->record_node_list), index);
			SN_FREE(record);

			return 0;
		}
	}

	return -1;
	
}
Exemple #10
0
void
osip_uri_param_freelist (osip_list_t * params)
{
  osip_uri_param_t *u_param;

  while (!osip_list_eol (params, 0))
    {
      u_param = (osip_uri_param_t *) osip_list_get (params, 0);
      osip_list_remove (params, 0);
      osip_uri_param_free (u_param);
    }
}
Exemple #11
0
void osip_list_ofchar_free(osip_list_t * li)
{
	int pos = 0;
	char *chain;

	if (li == NULL)
		return;
	while (!osip_list_eol(li, pos)) {
		chain = (char *) osip_list_get(li, pos);
		osip_list_remove(li, pos);
		osip_free(chain);
	}
}
Exemple #12
0
void osip_list_special_free(osip_list_t * li, void (*free_func) (void *))
{
	void *element;

	if (li == NULL)
		return;
	while (!osip_list_eol(li, 0)) {
		element = (void *) osip_list_get(li, 0);
		osip_list_remove(li, 0);
		if (free_func != NULL)
			free_func(element);
	}
}
int
sdp_message_m_payload_del (sdp_message_t * sdp, int pos_media, int pos)
{
  sdp_media_t *med = osip_list_get (&sdp->m_medias, pos_media);
  char *payload;

  if (med == NULL)
    return -1;
  if ((payload = osip_list_get (&med->m_payloads, pos)) == NULL)
    return -1;
  osip_list_remove (&med->m_payloads, pos);
  osip_free (payload);
  return 0;
}
Exemple #14
0
int
sdp_message_m_payload_del (sdp_message_t * sdp, int pos_media, int pos)
{
  sdp_media_t *med = osip_list_get (&sdp->m_medias, pos_media);
  char *payload;

  if (med == NULL)
    return OSIP_BADPARAMETER;
  if ((payload = osip_list_get (&med->m_payloads, pos)) == NULL)
    return OSIP_UNDEFINED_ERROR;
  osip_list_remove (&med->m_payloads, pos);
  osip_free (payload);
  return OSIP_SUCCESS;
}
Exemple #15
0
int
sdp_message_a_attribute_del (sdp_message_t * sdp, int pos_media, char *att_field)
{
  int i;
  sdp_media_t *med;
  sdp_attribute_t *attr;

  if (sdp == NULL)
    return OSIP_BADPARAMETER;
  if ((pos_media != -1) && (osip_list_size (&sdp->m_medias) < pos_media + 1))
    return OSIP_UNDEFINED_ERROR;
  if (pos_media == -1) {
    for (i = 0; i < osip_list_size (&sdp->a_attributes);) {
      attr = osip_list_get (&sdp->a_attributes, i);
      if (strcmp (attr->a_att_field, att_field) == 0) {
        osip_list_remove (&sdp->a_attributes, i);
        sdp_attribute_free (attr);
      }
      else
        i++;
    }
    return OSIP_SUCCESS;
  }
  med = (sdp_media_t *) osip_list_get (&sdp->m_medias, pos_media);
  if (med == NULL)
    return OSIP_UNDEFINED_ERROR;
  for (i = 0; i < osip_list_size (&med->a_attributes);) {
    attr = osip_list_get (&med->a_attributes, i);
    if (strcmp (attr->a_att_field, att_field) == 0) {
      osip_list_remove (&med->a_attributes, i);
      sdp_attribute_free (attr);
    }
    else
      i++;
  }
  return OSIP_SUCCESS;
}
void
__nict_unload_fsm ()
{
  transition_t *transition;
  osip_statemachine_t *statemachine = __nict_get_fsm ();

  while (!osip_list_eol (statemachine->transitions, 0))
    {
      transition = (transition_t *) osip_list_get (statemachine->transitions, 0);
      osip_list_remove (statemachine->transitions, 0);
      osip_free (transition);
    }
  osip_free (statemachine->transitions);
  osip_free (statemachine);
}
Exemple #17
0
int from_2char_without_params(osip_from_t *from,char **str)
{
	osip_from_t *tmpfrom=NULL;
	osip_from_clone(from,&tmpfrom);
	if (tmpfrom!=NULL){
		while(!osip_list_eol(&tmpfrom->gen_params,0)){
			osip_generic_param_t *param=(osip_generic_param_t*)osip_list_get(&tmpfrom->gen_params,0);
			osip_generic_param_free(param);
			osip_list_remove(&tmpfrom->gen_params,0);
		}
	}else return -1;
	osip_from_to_str(tmpfrom,str);
	osip_from_free(tmpfrom);
	return 0;
}
/* returns -1 on error. */
int
osip_message_replace_header (osip_message_t * sip, const char *hname,
			     const char *hvalue)
{
  osip_header_t *h, *oldh;
  int i, oldpos = -1;

  if (sip == NULL || hname == NULL)
    return OSIP_BADPARAMETER;

  oldpos = osip_message_header_get_byname(sip, hname, 0, &oldh);

  i = osip_header_init (&h);
  if (i != 0)
    return i;

  h->hname = (char *) osip_malloc (strlen (hname) + 1);

  if (h->hname == NULL)
    {
      osip_header_free (h);
      return OSIP_NOMEM;
    }
  osip_clrncpy (h->hname, hname, strlen (hname));

  if (hvalue != NULL)
    {                           /* some headers can be null ("subject:") */
      h->hvalue = (char *) osip_malloc (strlen (hvalue) + 1);
      if (h->hvalue == NULL)
	{
	  osip_header_free (h);
	  return OSIP_NOMEM;
	}
      osip_clrncpy (h->hvalue, hvalue, strlen (hvalue));
    } else
      h->hvalue = NULL;

  if (oldpos != -1)
    {
      osip_list_remove(&sip->headers, oldpos);
      osip_header_free(oldh);
    }

  sip->message_property = 2;
  osip_list_add (&sip->headers, h, -1);
  return OSIP_SUCCESS;                     /* ok */
}
void
osip_list_special_free (osip_list_t * li, void *(*free_func) (void *))
{
  int pos = 0;
  void *element;

  if (li == NULL)
    return;
  while (!osip_list_eol (li, pos))
    {
      element = (void *) osip_list_get (li, pos);
      osip_list_remove (li, pos);
      if (free_func!=NULL)
	free_func (element);
    }
  osip_free (li);
}
Exemple #20
0
void *
osip_fifo_tryget (osip_fifo_t * ff)
{
  void *el;

#ifdef OSIP_MT
  if (0 != osip_sem_trywait (ff->qisempty))
    {				/* no elements... */
      return NULL;
    }
  osip_mutex_lock (ff->qislocked);
#else
  if (ff->etat == vide)
    return NULL;
#endif

  if (ff->etat != vide)
    {
      el = osip_list_get (ff->queue, 0);
      osip_list_remove (ff->queue, 0);
      /* ff->nb_elt--; */
    }
#ifdef OSIP_MT
  else
    {				/* this case MUST never happen... */
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_INFO4, NULL,
		   "no element in fifo.\n"));
      osip_mutex_unlock (ff->qislocked);
      return 0;
    }
#endif

  /* if (ff->nb_elt <= 0) */
  if (osip_list_size (ff->queue) <= 0)
    ff->etat = vide;
  else
    ff->etat = ok;

#ifdef OSIP_MT
  osip_mutex_unlock (ff->qislocked);
#endif
  return el;
}
/*
 * SIP_DEL_MYVIA
 *
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 */
int sip_del_myvia (sip_ticket_t *ticket, struct in_addr *local_ip) {
   osip_via_t *via;
   int sts;

   DEBUGC(DBCLASS_PROXY,"deleting topmost VIA");
   via = osip_list_get (ticket->sipmsg->vias, 0);
   
   if ( via == NULL ) {
      ERROR("Got empty VIA list - is your UA configured properly?");
      return STS_FAILURE;
   }

   if ( is_via_local(via, local_ip) == STS_FALSE ) {
      ERROR("I'm trying to delete a VIA but it's not mine! host=%s",via->host);
      return STS_FAILURE;
   }

   sts = osip_list_remove(ticket->sipmsg->vias, 0);
   osip_via_free (via);
   return STS_SUCCESS;
}
void *
osip_fifo_get (osip_fifo_t * ff)
{
  void *el = NULL;

#ifdef OSIP_MT
  int i = osip_sem_wait (ff->qisempty);

  if (i != 0)
    return NULL;
  osip_mutex_lock (ff->qislocked);
#endif

  if (ff->state != osip_empty)
    {
      el = osip_list_get (&ff->queue, 0);
      osip_list_remove (&ff->queue, 0);
      /* ff->nb_elt--; */
  } else
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL, "no element in fifo.\n"));
#ifdef OSIP_MT
      osip_mutex_unlock (ff->qislocked);
#endif
      return 0;                 /* pile vide */
    }
  /* if (ff->nb_elt <= 0) */
  if (osip_list_size (&ff->queue) <= 0)
    ff->state = osip_empty;
  else
    ff->state = osip_ok;

#ifdef OSIP_MT
  osip_mutex_unlock (ff->qislocked);
#endif
  return el;
}
/* INPUT : osip_body_t *body | body.  */
void
osip_body_free (osip_body_t * body)
{
  if (body == NULL)
    return;
  osip_free (body->body);
  if (body->content_type != NULL)
    {
      osip_content_type_free (body->content_type);
    }

  {
    osip_header_t *header;

    while (!osip_list_eol (body->headers, 0))
      {
	header = (osip_header_t *) osip_list_get (body->headers, 0);
	osip_list_remove (body->headers, 0);
	osip_header_free (header);
      }
    osip_free (body->headers);
  }
  osip_free (body);
}
Exemple #24
0
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;
}
Exemple #25
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 (&reg, tr) == 0)
            {
              memcpy (&(reg->addr), &addr, len);
              reg->len = len;
            }
        }
    }

  osip_free (message);
  return OSIP_SUCCESS;
}
Exemple #26
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(&reg, 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;
}
Exemple #27
0
/*
 * PROXY_REWRITE_INVITATION_BODY
 *
 * rewrites the outgoing INVITATION request or response packet
 * 
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 */
int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){
   osip_body_t *body;
   sdp_message_t  *sdp;
   struct in_addr map_addr, addr_sess, addr_media, outside_addr, inside_addr;
   int sts;
   char *bodybuff;
   int bodybuflen;
   char clen[8]; /* content length: probably never more than 7 digits !*/
   int map_port, msg_port;
   int media_stream_no;
   sdp_connection_t *sdp_conn;
   sdp_media_t *sdp_med;
   int rtp_direction=0;
   int have_c_media=0;

   if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS;

   /*
    * get SDP structure
    */
   sts = osip_message_get_body(mymsg, 0, &body);
   if (sts != 0) {
#if 0
      if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) &&
          (MSG_IS_STATUS_1XX(mymsg))) {
         /* 1xx responses *MAY* contain SDP data */
         DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
                "no body found in message");
         return STS_SUCCESS;
      } else {
         /* INVITE request and 200 response *MUST* contain SDP data */
         ERROR("rewrite_invitation_body: no body found in message");
         return STS_FAILURE;
      }
#else
      DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
                            "no body found in message");
      return STS_SUCCESS;
#endif
   }

   sts = sip_body_to_str(body, &bodybuff, &bodybuflen);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sip_body_to_str");
   }
   sts = sdp_message_init(&sdp);
   sts = sdp_message_parse (sdp, bodybuff);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sdp_message_parse body");
      DUMP_BUFFER(-1, bodybuff, bodybuflen);
      osip_free(bodybuff);
      sdp_message_free(sdp);
      return STS_FAILURE;
   }
   osip_free(bodybuff);


if (configuration.debuglevel)
{ /* just dump the buffer */
   char *tmp, *tmp2;
   int tmplen;
   sts = osip_message_get_body(mymsg, 0, &body);
   sts = sip_body_to_str(body, &tmp, &tmplen);
   osip_content_length_to_str(mymsg->content_length, &tmp2);
   DEBUG("Body before rewrite (clen=%s, strlen=%i):\n%s\n----",
         tmp2, tmplen, tmp);
   osip_free(tmp);
   osip_free(tmp2);
}

   /*
    * RTP proxy: get ready and start forwarding
    * start forwarding for each media stream ('m=' item in SIP message)
    */

   /* get outbound address */
   if (get_interface_ip(IF_OUTBOUND, &outside_addr) != STS_SUCCESS) {
      sdp_message_free(sdp);
      return STS_FAILURE;
   }

   /* get inbound address */
   if (get_interface_ip(IF_INBOUND, &inside_addr) != STS_SUCCESS) {
      sdp_message_free(sdp);
      return STS_FAILURE;
   }

   /* figure out what address to use for RTP masquerading */
   if (MSG_IS_REQUEST(mymsg)) {
      if (direction == DIR_INCOMING) {
         memcpy(&map_addr, &inside_addr, sizeof (map_addr));
         rtp_direction = DIR_OUTGOING;
      } else {
         memcpy(&map_addr, &outside_addr, sizeof (map_addr));
         rtp_direction = DIR_INCOMING;
      }
   } else /* MSG_IS_REPONSE(mymsg) */ {
      if (direction == DIR_INCOMING) {
         memcpy(&map_addr, &inside_addr, sizeof (map_addr));
         rtp_direction = DIR_OUTGOING;
      } else {
         memcpy(&map_addr, &outside_addr, sizeof (map_addr));
         rtp_direction = DIR_INCOMING;
      }
   }

   DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: SIP[%s %s] RTP[%s %s]",
          MSG_IS_REQUEST(mymsg)? "RQ" : "RS",
          (direction==DIR_INCOMING)? "IN" : "OUT",
          (rtp_direction==DIR_INCOMING)? "IN" : "OUT",
          utils_inet_ntoa(map_addr));


   /*
    * first, check presence of a 'c=' item on session level
    */
   if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) {
      /*
       * No 'c=' on session level, search on media level now
       *
       * According to RFC2327, ALL media description must
       * include a 'c=' item now:
       */
      media_stream_no=0;
      while (!sdp_message_endof_media(sdp, media_stream_no)) {
         /* check if n'th media stream is present */
         if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) {
            ERROR("SDP: have no 'c=' on session level and neither "
                  "on media level (media=%i)",media_stream_no);
            sdp_message_free(sdp);
            return STS_FAILURE;
         }
         media_stream_no++;
      } /* while */
   }

   /* Required 'c=' items ARE present */


   /*
    * rewrite 'c=' item on session level if present and not yet done.
    * remember the original address in addr_sess
    */
   memset(&addr_sess, 0, sizeof(addr_sess));
   if (sdp->c_connection && sdp->c_connection->c_addr) {
      sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess);
      if (sts == STS_FAILURE) {
         ERROR("SDP: cannot resolve session 'c=' host [%s]",
               sdp->c_connection->c_addr);
         sdp_message_free(sdp);
         return STS_FAILURE;
      }
      /*
       * Rewrite
       * an IP address of 0.0.0.0 means *MUTE*, don't rewrite such
       */
      if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) {
         osip_free(sdp->c_connection->c_addr);
         sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE);
         sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr));
      } else {
         /* 0.0.0.0 - don't rewrite */
         DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                "got a MUTE c= record (on session level - legal?)");
      }
   }


   /*
    * rewrite 'o=' item (originator) on session level if present.
    */
   if (sdp->o_addrtype && sdp->o_addr) {
      if (strcmp(sdp->o_addrtype, "IP4") != 0) {
         ERROR("got IP6 in SDP originator - not yet suported by siproxd");
         sdp_message_free(sdp);
         return STS_FAILURE;
      }

      osip_free(sdp->o_addr);
      sdp->o_addr=osip_malloc(HOSTNAME_SIZE);
      sprintf(sdp->o_addr, "%s", utils_inet_ntoa(map_addr));
   }


   /*
    * loop through all media descritions,
    * start RTP proxy and rewrite them
    */
   for (media_stream_no=0;;media_stream_no++) {
      /* check if n'th media stream is present */
      if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break;

      /*
       * check if a 'c=' item is present in this media description,
       * if so -> rewrite it
       */
      memset(&addr_media, 0, sizeof(addr_media));
      have_c_media=0;
      sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0);
      if (sdp_conn && sdp_conn->c_addr) {
         if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) {
            sts = get_ip_by_host(sdp_conn->c_addr, &addr_media);
            have_c_media=1;
            /* have a valid address */
            osip_free(sdp_conn->c_addr);
            sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE);
            sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr));
         } else {
            /* 0.0.0.0 - don't rewrite */
            DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a "
                   "MUTE c= record (media level)");
         }
      }

      /* start an RTP proxying stream */
      if (sdp_message_m_port_get(sdp, media_stream_no)) {
         msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no));

         if (msg_port > 0) {
            osip_uri_t *cont_url = NULL;
            char *client_id=NULL;
            /* try to get some additional UA specific unique ID.
             * Try:
             * 1) User part of Contact header
             * 2) Host part of Contact header (will be different
             *    between internal UA and external UA)
             */
            if (!osip_list_eol(mymsg->contacts, 0))
               cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url;
            if (cont_url) {
               client_id=cont_url->username;
               if (client_id == NULL) client_id=cont_url->host;
            }


            /*
             * do we have a 'c=' item on media level?
             * if not, use the same as on session level
             */
            if (have_c_media == 0) {
               memcpy(&addr_media, &addr_sess, sizeof(addr_sess));
            }

            /*
             * Am I running in front of the routing device? Then I cannot
             * use the external IP to bind a listen socket to, so force
             * the use of my inbound IP for listening.
             */
            if ((rtp_direction == DIR_INCOMING) &&
                (configuration.outbound_host) &&
                (strcmp(configuration.outbound_host, "")!=0)) {
               DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                      "in-front-of-NAT-Router");
               memcpy(&map_addr, &inside_addr, sizeof (map_addr));
            }

            sts = rtp_start_fwd(osip_message_get_call_id(mymsg),
                                client_id,
                                rtp_direction,
                                media_stream_no,
                                map_addr, &map_port,
                                addr_media, msg_port);

            if (sts == STS_SUCCESS) {
               /* and rewrite the port */
               sdp_med=osip_list_get(sdp->m_medias, media_stream_no);
               if (sdp_med && sdp_med->m_port) {
                  osip_free(sdp_med->m_port);
                  sdp_med->m_port=osip_malloc(8); /* 5 digits, \0 + align */
                  sprintf(sdp_med->m_port, "%i", map_port);
                  DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                         "m= rewrote port to [%i]",map_port);
               } else {
                  ERROR("rewriting port in m= failed sdp_med=%p, "
                        "m_number_of_port=%p", sdp_med, sdp_med->m_port);
               }
            } /* sts == success */
         } /* if msg_port > 0 */
      } else {
         /* no port defined - skip entry */
         WARN("no port defined in m=(media) stream_no=%i", media_stream_no);
         continue;
      }
   } /* for media_stream_no */

   /* remove old body */
   sts = osip_list_remove(mymsg->bodies, 0);
   osip_body_free(body);

   /* dump new body */
   sdp_message_to_str(sdp, &bodybuff);
   bodybuflen=strlen(bodybuff);

   /* free sdp structure */
   sdp_message_free(sdp);

   /* include new body */
   sip_message_set_body(mymsg, bodybuff, bodybuflen);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sip_message_set_body body");
   }

   /* free content length resource and include new one*/
   osip_content_length_free(mymsg->content_length);
   mymsg->content_length=NULL;
   sprintf(clen,"%i",bodybuflen);
   sts = osip_message_set_content_length(mymsg, clen);

   /* free old body */
   osip_free(bodybuff);

if (configuration.debuglevel)
{ /* just dump the buffer */
   char *tmp, *tmp2;
   int tmplen;
   sts = osip_message_get_body(mymsg, 0, &body);
   sts = sip_body_to_str(body, &tmp, &tmplen);
   osip_content_length_to_str(mymsg->content_length, &tmp2);
   DEBUG("Body after rewrite (clen=%s, strlen=%i):\n%s\n----",
         tmp2, tmplen, tmp);
   osip_free(tmp);
   osip_free(tmp2);
}
   return STS_SUCCESS;
}
int
_eXosip_insubscription_send_request_with_credential (eXosip_notify_t * jn,
        eXosip_dialog_t * jd,
        osip_transaction_t * out_tr)
{
    osip_transaction_t *tr = NULL;
    osip_message_t *msg = NULL;
    osip_event_t *sipevent;

    char locip[256];
    int cseq;
    char tmp[256];
    osip_via_t *via;
    int i;

    if (jn == NULL)
        return -1;
    if (jd != NULL)
    {
        if (jd->d_out_trs == NULL)
            return -1;
    }

    if (out_tr == NULL)
    {
        out_tr = eXosip_find_last_out_notify (jn, jd);
    }

    if (out_tr == NULL
            || out_tr->orig_request == NULL || out_tr->last_response == NULL)
        return -1;

    osip_message_clone (out_tr->orig_request, &msg);
    if (msg == NULL)
    {
        OSIP_TRACE (osip_trace
                    (__FILE__, __LINE__, OSIP_ERROR, NULL,
                     "eXosip: could not clone msg for authentication\n"));
        return -1;
    }

    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 -1;
    }

    /* 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++;
    }

    osip_list_remove (msg->vias, 0);
    osip_via_free (via);

    i = _eXosip_find_protocol (out_tr->orig_request);
    if (i == IPPROTO_UDP)
    {
        eXosip_guess_ip_for_via (eXosip.net_interfaces[0].net_ip_family, locip,
                                 sizeof (locip));
        if (eXosip.net_interfaces[0].net_ip_family == AF_INET6)
            snprintf (tmp, 256, "SIP/2.0/UDP [%s]:%s;branch=z9hG4bK%u",
                      locip, eXosip.net_interfaces[0].net_port,
                      via_branch_new_random ());
        else
            snprintf (tmp, 256, "SIP/2.0/UDP %s:%s;rport;branch=z9hG4bK%u",
                      locip, eXosip.net_interfaces[0].net_port,
                      via_branch_new_random ());
    } else if (i == IPPROTO_TCP)
    {
        eXosip_guess_ip_for_via (eXosip.net_interfaces[1].net_ip_family, locip,
                                 sizeof (locip));
        if (eXosip.net_interfaces[1].net_ip_family == AF_INET6)
            snprintf (tmp, 256, "SIP/2.0/TCP [%s]:%s;branch=z9hG4bK%u",
                      locip, eXosip.net_interfaces[1].net_port,
                      via_branch_new_random ());
        else
            snprintf (tmp, 256, "SIP/2.0/TCP %s:%s;rport;branch=z9hG4bK%u",
                      locip, eXosip.net_interfaces[1].net_port,
                      via_branch_new_random ());
    } else
    {
        /* tls? */
        osip_message_free (msg);
        OSIP_TRACE (osip_trace
                    (__FILE__, __LINE__, OSIP_ERROR, NULL,
                     "eXosip: unsupported protocol\n"));
        return -1;
    }

    osip_via_init (&via);
    osip_via_parse (via, tmp);
    osip_list_add (msg->vias, via, 0);

    eXosip_add_authentication_information (msg, out_tr->last_response);
    osip_message_force_update (msg);

    i = osip_transaction_init (&tr, NICT, eXosip.j_osip, msg);

    if (i != 0)
    {
        osip_message_free (msg);
        return -1;
    }

    /* add the new tr for the current dialog */
    osip_list_add (jd->d_out_trs, tr, 0);

    sipevent = osip_new_outgoing_sipmessage (msg);

    osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (NULL, jd, NULL, jn));
    osip_transaction_add_event (tr, sipevent);

    eXosip_update ();             /* fixed? */
    __eXosip_wakeup ();
    return 0;
}
Exemple #29
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 #30
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;
}