Beispiel #1
0
int
_eXosip_dialog_add_contact (osip_message_t * request, osip_message_t * answer)
{
  osip_via_t *via;
  osip_from_t *a_from;
  char *contact = NULL;
  char locip[65];
  char firewall_ip[65];
  char firewall_port[10];
  int len;

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

  if (eXosip.eXtl->tl_get_masquerade_contact != NULL)
    {
      eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip),
                                              firewall_port,
                                              sizeof (firewall_port));
    }

  /* search for topmost Via which indicate the transport protocol */
  via = (osip_via_t *) osip_list_get (&request->vias, 0);
  if (via == NULL || via->protocol == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: missing via header\n"));
      return OSIP_SYNTAXERROR;
    }

  if (answer == NULL)
    a_from = request->from;
  else
    a_from = answer->to;

  if (a_from == NULL || a_from->url == NULL)
    return OSIP_SYNTAXERROR;

  /*guess the local ip since req uri is known */
  memset (locip, '\0', sizeof (locip));

  if (a_from->url->username != NULL)
    len =
      2 + 4 + strlen (a_from->url->username) + 1 + 100 + 6 + 10 +
      strlen (eXosip.transport);
  else
    len = 2 + 4 + 100 + 6 + 10 + strlen (eXosip.transport);

  contact = (char *) osip_malloc (len + 1);
  if (contact == NULL)
    return OSIP_NOMEM;
  if (firewall_ip[0] != '\0')
    {
      char *c_address = request->req_uri->host;

      struct addrinfo *addrinfo;
      struct __eXosip_sockaddr addr;
      int i;

      i =
        eXosip_get_addrinfo (&addrinfo, request->req_uri->host, 5060, IPPROTO_TCP);
      if (i == 0)
        {
          memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
          eXosip_freeaddrinfo (addrinfo);
          c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
                                  "eXosip: here is the resolved destination host=%s\n",
                                  c_address));
        }

      if (eXosip_is_public_address (c_address))
        {
          memcpy (locip, firewall_ip, sizeof (locip));
        }
    }

  if (locip[0] == '\0')
    {
      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;
        }
    }

  if (eXosip.eXtl->proto_family == AF_INET6)
    {
      if (a_from->url->username != NULL)
        snprintf (contact, len, "<sip:%s@[%s]:%s>", a_from->url->username,
                  locip, firewall_port);
      else
        snprintf (contact, len - strlen (eXosip.transport) - 10, "<sip:[%s]:%s>",
                  locip, firewall_port);
  } else
    {
      if (a_from->url->username != NULL)
        snprintf (contact, len, "<sip:%s@%s:%s>", a_from->url->username,
                  locip, firewall_port);
      else
        snprintf (contact, len - strlen (eXosip.transport) - 10, "<sip:%s:%s>",
                  locip, firewall_port);
    }
  if (osip_strcasecmp (eXosip.transport, "UDP") != 0)
    {
      contact[strlen (contact) - 1] = '\0';
      strcat (contact, ";transport=");
      strcat (contact, eXosip.transport);
      strcat (contact, ">");
    }
  osip_message_set_contact (request, contact);
  osip_free (contact);

  return OSIP_SUCCESS;
}
Beispiel #2
0
int
_eXosip_build_request_within_dialog (osip_message_t ** dest,
                                     const char *method,
                                     osip_dialog_t * dialog, const char *transport)
{
  int i;
  osip_message_t *request;
  char locip[65];
  char firewall_ip[65];
  char firewall_port[10];

  *dest = NULL;

  if (dialog == NULL)
    return OSIP_BADPARAMETER;

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

  if (eXosip.eXtl->tl_get_masquerade_contact != NULL)
    {
      eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip),
                                              firewall_port,
                                              sizeof (firewall_port));
    }

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

  if (dialog->remote_contact_uri == NULL)
    {
      /* this dialog is probably not established! or the remote UA
         is not compliant with the latest RFC
       */
      osip_message_free (request);
      return OSIP_SYNTAXERROR;
    }


  memset (locip, '\0', sizeof (locip));
  eXosip_guess_ip_for_via (eXosip.eXtl->proto_family, locip, 49);
  if (locip[0] == '\0')
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: no default interface defined\n"));
      osip_message_free (request);
      return OSIP_NO_NETWORK;
    }

  /* prepare the request-line */
  request->sip_method = osip_strdup (method);
  if (request->sip_method == NULL)
    {
      osip_message_free (request);
      return OSIP_NOMEM;
    }
  request->sip_version = osip_strdup ("SIP/2.0");
  if (request->sip_version == NULL)
    {
      osip_message_free (request);
      return OSIP_NOMEM;
    }
  request->status_code = 0;
  request->reason_phrase = NULL;

  /* and the request uri???? */
  if (osip_list_eol (&dialog->route_set, 0))
    {
      /* The UAC must put the remote target URI (to field) in the req_uri */
      i = osip_uri_clone (dialog->remote_contact_uri->url, &(request->req_uri));
      if (i != 0)
        {
          osip_message_free (request);
          return i;
        }
  } else
    {
      /* fill the request-uri, and the route headers. */
      i = dialog_fill_route_set (dialog, request);
      if (i != 0)
        {
          osip_message_free (request);
          return i;
        }
    }

  /* To and From already contains the proper tag! */
  i = osip_to_clone (dialog->remote_uri, &(request->to));
  if (i != 0)
    {
      osip_message_free (request);
      return i;
    }
  i = osip_from_clone (dialog->local_uri, &(request->from));
  if (i != 0)
    {
      osip_message_free (request);
      return i;
    }

  /* set the cseq and call_id header */
  osip_message_set_call_id (request, dialog->call_id);

  if (0 == strcmp ("ACK", method))
    {
      osip_cseq_t *cseq;
      char *tmp;

      i = osip_cseq_init (&cseq);
      if (i != 0)
        {
          osip_message_free (request);
          return i;
        }
      tmp = osip_malloc (20);
      if (tmp == NULL)
        {
          osip_message_free (request);
          return OSIP_NOMEM;
        }
      sprintf (tmp, "%i", dialog->local_cseq);
      osip_cseq_set_number (cseq, tmp);
      osip_cseq_set_method (cseq, osip_strdup (method));
      request->cseq = cseq;
  } else
    {
      osip_cseq_t *cseq;
      char *tmp;

      i = osip_cseq_init (&cseq);
      if (i != 0)
        {
          osip_message_free (request);
          return i;
        }
      dialog->local_cseq++;     /* we should we do that?? */
      tmp = osip_malloc (20);
      if (tmp == NULL)
        {
          osip_message_free (request);
          return OSIP_NOMEM;
        }
      sprintf (tmp, "%i", dialog->local_cseq);
      osip_cseq_set_number (cseq, tmp);
      osip_cseq_set_method (cseq, osip_strdup (method));
      request->cseq = cseq;
    }

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


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

  /* add specific headers for each kind of request... */

  {
    char contact[200];

    if (firewall_ip[0] != '\0')
      {
        char *c_address = request->req_uri->host;

        struct addrinfo *addrinfo;
        struct __eXosip_sockaddr addr;

        i =
          eXosip_get_addrinfo (&addrinfo, request->req_uri->host, 5060,
                               IPPROTO_UDP);
        if (i == 0)
          {
            memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
            eXosip_freeaddrinfo (addrinfo);
            c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
            OSIP_TRACE (osip_trace
                        (__FILE__, __LINE__, OSIP_INFO1, NULL,
                         "eXosip: here is the resolved destination host=%s\n",
                         c_address));
          }

        if (eXosip_is_public_address (c_address))
          {
            sprintf (contact, "<sip:%s@%s:%s>",
                     dialog->local_uri->url->username, firewall_ip, firewall_port);
        } else
          {
            sprintf (contact, "<sip:%s@%s:%s>",
                     dialog->local_uri->url->username, locip, firewall_port);
          }
    } else
      {
        sprintf (contact, "<sip:%s@%s:%s>", dialog->local_uri->url->username,
                 locip, firewall_port);
      }
    osip_message_set_contact (request, contact);
    /* Here we'll add the supported header if it's needed! */
    /* the require header must be added by the upper layer if needed */
  }

  if (0 == strcmp ("NOTIFY", method))
    {
  } else if (0 == strcmp ("INFO", method))
    {

  } else if (0 == strcmp ("OPTIONS", method))
    {
      osip_message_set_accept (request, "application/sdp");
  } else if (0 == strcmp ("ACK", method))
    {
      /* The ACK MUST contains the same credential than the INVITE!! */
      /* TODO... */
    }

  osip_message_set_user_agent (request, eXosip.user_agent);
  /*  else if ... */
  *dest = request;
  return OSIP_SUCCESS;
}
int
complete_answer_that_establish_a_dialog (osip_message_t * response,
                                         osip_message_t * request)
{
  int i;
  int pos = 0;
  char contact[1000];
  char locip[50];
  struct eXosip_net *net;

  /* 12.1.1:
     copy all record-route in response
     add a contact with global scope
   */
  while (!osip_list_eol (request->record_routes, pos))
    {
      osip_record_route_t *rr;
      osip_record_route_t *rr2;

      rr = osip_list_get (request->record_routes, pos);
      i = osip_record_route_clone (rr, &rr2);
      if (i != 0)
        return -1;
      osip_list_add (response->record_routes, rr2, -1);
      pos++;
    }

  i = _eXosip_find_protocol (response);
  if (i == IPPROTO_UDP)
    {
      net = &eXosip.net_interfaces[0];
  } else if (i == IPPROTO_TCP)
    {
      net = &eXosip.net_interfaces[1];
  } else
    {
      net = &eXosip.net_interfaces[0];
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: unsupported protocol (default to UDP)\n"));
      return -1;
    }

#ifdef SM
  eXosip_get_localip_from_via (response, locip, 49);
#else
  eXosip_guess_ip_for_via (net->net_ip_family, locip, 49);
#endif

  if (request->to->url->username == NULL)
    snprintf (contact, 1000, "<sip:%s:%s>", locip, net->net_port);
  else
    snprintf (contact, 1000, "<sip:%s@%s:%s>", request->to->url->username,
              locip, net->net_port);

  if (eXosip.net_interfaces[0].net_firewall_ip[0] != '\0')
    {
      osip_contact_t *con =
        (osip_contact_t *) osip_list_get (request->contacts, 0);
      if (con != NULL && con->url != NULL && con->url->host != NULL)
        {
          char *c_address = con->url->host;

          struct addrinfo *addrinfo;
          struct __eXosip_sockaddr addr;

          i = eXosip_get_addrinfo (&addrinfo, con->url->host, 5060, IPPROTO_UDP);
          if (i == 0)
            {
              memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
              freeaddrinfo (addrinfo);
              c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
              OSIP_TRACE (osip_trace
                          (__FILE__, __LINE__, OSIP_INFO1, NULL,
                           "eXosip: here is the resolved destination host=%s\n",
                           c_address));
            }

          /* If c_address is a PUBLIC address, the request was
             coming from the PUBLIC network. */
          if (eXosip_is_public_address (c_address))
            {
              if (request->to->url->username == NULL)
                snprintf (contact, 1000, "<sip:%s:%s>",
                          eXosip.net_interfaces[0].net_firewall_ip, net->net_port);
              else
                snprintf (contact, 1000, "<sip:%s@%s:%s>",
                          request->to->url->username,
                          eXosip.net_interfaces[0].net_firewall_ip, net->net_port);
            }
        }
    }

  osip_message_set_contact (response, contact);

  return 0;
}
Beispiel #4
0
int
generating_register (eXosip_reg_t * jreg, osip_message_t ** reg, char *transport,
                     char *from, char *proxy, char *contact, int expires)
{
  int i;
  char locip[65];
  char firewall_ip[65];
  char firewall_port[10];
  if (eXosip.eXtl == NULL)
    return OSIP_NO_NETWORK;

  if (eXosip.eXtl->tl_get_masquerade_contact != NULL)
    {
      eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip),
                                              firewall_port,
                                              sizeof (firewall_port));
    }

  i =
    generating_request_out_of_dialog (reg, "REGISTER", NULL, transport, from,
                                      proxy);
  if (i != 0)
    return i;

  memset (locip, '\0', sizeof (locip));
  eXosip_guess_ip_for_via (eXosip.eXtl->proto_family, locip, 49);

  if (locip[0] == '\0')
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: no default interface defined\n"));
      osip_message_free (*reg);
      *reg = NULL;
      return OSIP_NO_NETWORK;
    }

  if (contact == NULL)
    {
      osip_contact_t *new_contact = NULL;
      osip_uri_t *new_contact_url = NULL;

      i = osip_contact_init (&new_contact);
      if (i == 0)
        i = osip_uri_init (&new_contact_url);

      new_contact->url = new_contact_url;

      if (i == 0 && (*reg)->from != NULL
          && (*reg)->from->url != NULL && (*reg)->from->url->username != NULL)
        {
          new_contact_url->username = osip_strdup ((*reg)->from->url->username);
        }

      if (i == 0 && (*reg)->from != NULL && (*reg)->from->url != NULL)
        {
          /* serach for correct ip */
          if (firewall_ip[0] != '\0')
            {
              char *c_address = (*reg)->req_uri->host;

              struct addrinfo *addrinfo;
              struct __eXosip_sockaddr addr;

              i =
                eXosip_get_addrinfo (&addrinfo, (*reg)->req_uri->host, 5060,
                                     IPPROTO_UDP);
              if (i == 0)
                {
                  memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
                  eXosip_freeaddrinfo (addrinfo);
                  c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
                  OSIP_TRACE (osip_trace
                              (__FILE__, __LINE__, OSIP_INFO1, NULL,
                               "eXosip: here is the resolved destination host=%s\n",
                               c_address));
                }

              if (eXosip_is_public_address (c_address))
                {
                  new_contact_url->host = osip_strdup (firewall_ip);
                  new_contact_url->port = osip_strdup (firewall_port);
              } else
                {
                  new_contact_url->host = osip_strdup (locip);
                  new_contact_url->port = osip_strdup (firewall_port);
                }
          } else
            {
              new_contact_url->host = osip_strdup (locip);
              new_contact_url->port = osip_strdup (firewall_port);
            }

          if (transport != NULL && osip_strcasecmp (transport, "UDP") != 0)
            {
              osip_uri_uparam_add (new_contact_url, osip_strdup ("transport"),
                                   osip_strdup (transport));
            }

          if (jreg->r_line[0] != '\0')
            {
              osip_uri_uparam_add (new_contact_url, osip_strdup ("line"),
                                   osip_strdup (jreg->r_line));
            }

          osip_list_add (&(*reg)->contacts, new_contact, -1);
        }
  } else
    {
      osip_message_set_contact (*reg, contact);
    }

  {
    char exp[10];               /* MUST never be ouside 1 and 3600 */

    snprintf (exp, 9, "%i", expires);
    osip_message_set_expires (*reg, exp);
  }

  osip_message_set_content_length (*reg, "0");

  return OSIP_SUCCESS;
}
Beispiel #5
0
int
complete_answer_that_establish_a_dialog (osip_message_t * response,
                                         osip_message_t * request)
{
  int i;
  int pos = 0;
  char contact[1024];
  char locip[65];
  char firewall_ip[65];
  char firewall_port[10];
  if (eXosip.eXtl->tl_get_masquerade_contact != NULL)
    {
      eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip),
                                              firewall_port,
                                              sizeof (firewall_port));
    }

  /* 12.1.1:
     copy all record-route in response
     add a contact with global scope
   */
  while (!osip_list_eol (&request->record_routes, pos))
    {
      osip_record_route_t *rr;
      osip_record_route_t *rr2;

      rr = osip_list_get (&request->record_routes, pos);
      i = osip_record_route_clone (rr, &rr2);
      if (i != 0)
        return i;
      osip_list_add (&response->record_routes, rr2, -1);
      pos++;
    }

  memset (locip, '\0', sizeof (locip));
  eXosip_guess_ip_for_via (eXosip.eXtl->proto_family, locip, 49);

  if (request->to->url->username == NULL)
    snprintf (contact, 1000, "<sip:%s:%s>", locip, firewall_port);
  else
    snprintf (contact, 1000, "<sip:%s@%s:%s>", request->to->url->username,
              locip, firewall_port);

  if (firewall_ip[0] != '\0')
    {
      osip_contact_t *con =
        (osip_contact_t *) osip_list_get (&request->contacts, 0);
      if (con != NULL && con->url != NULL && con->url->host != NULL)
        {
          char *c_address = con->url->host;

          struct addrinfo *addrinfo;
          struct __eXosip_sockaddr addr;

          i = eXosip_get_addrinfo (&addrinfo, con->url->host, 5060, IPPROTO_UDP);
          if (i == 0)
            {
              memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
              eXosip_freeaddrinfo (addrinfo);
              c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
              OSIP_TRACE (osip_trace
                          (__FILE__, __LINE__, OSIP_INFO1, NULL,
                           "eXosip: here is the resolved destination host=%s\n",
                           c_address));
            }

          /* If c_address is a PUBLIC address, the request was
             coming from the PUBLIC network. */
          if (eXosip_is_public_address (c_address))
            {
              if (request->to->url->username == NULL)
                snprintf (contact, 1000, "<sip:%s:%s>",
                          firewall_ip, firewall_port);
              else
                snprintf (contact, 1000, "<sip:%s@%s:%s>",
                          request->to->url->username, firewall_ip, firewall_port);
            }
        }
    }

  {
    osip_via_t *via;

    via = (osip_via_t *) osip_list_get (&response->vias, 0);
    if (via == NULL || via->protocol == NULL)
      return OSIP_SYNTAXERROR;
    if (strlen (contact) + strlen (via->protocol) < 1024
        && 0 != osip_strcasecmp (via->protocol, "UDP"))
      {
        contact[strlen (contact) - 1] = '\0';
        strcat (contact, ";transport=");
        strcat (contact, via->protocol);
        strcat (contact, ">");
      }
  }

  osip_message_set_contact (response, contact);

  return OSIP_SUCCESS;
}