Beispiel #1
0
int
osip_via_match (osip_via_t * via1, osip_via_t * via2)
{
  /* Can I really compare it this way??
     There exist matching rules for via header, but this method
     should only be used to detect retransmissions so the result should
     be exactly equivalent. (This may not be true if the retransmission
     traverse a different set of proxy...  */
  char *_via1;
  char *_via2;
  int i;

  if (via1 == NULL || via2 == NULL)
    return -1;
  i = osip_via_to_str (via1, &_via1);
  if (i != 0)
    return -1;
  i = osip_via_to_str (via2, &_via2);
  if (i != 0)
    {
      osip_free (_via1);
      return -1;
    }

  i = strcmp (_via1, _via2);
  osip_free (_via1);
  osip_free (_via2);
  if (i != 0)
    return -1;
  return 0;
}
Beispiel #2
0
        void SIPBuilder::CameraInfoAck(osip_message_t* msg,
                char** rtmsg, size_t* rtlen)
        {
            string head_line("SIP/2.0 200 OK\r\n");

            osip_via_t *via;
            char* via_c = NULL; 
            if( !osip_list_eol (&msg->vias, 0))
            {
                via = (osip_via_t *) osip_list_get (&msg->vias, 0);
                osip_via_to_str( via, &via_c);
            }else{
                return;
            }
            string via_header(via_c);
            via_header = string("Via: ")+via_header+string("\r\n");
            
            char* from_tag_c;
            osip_from_to_str( msg->from, &from_tag_c );
            string from_header(from_tag_c);
            from_header = string("From: ")+from_header+string("\r\n");

            char* to_tag_c;
            osip_to_to_str( msg->to, &to_tag_c );
            string to_header(to_tag_c);
            string to_tag_num = _RandomNum();
            to_header = to_header + ";tag="+to_tag_num;
            to_header = string("To: ")+to_header+string("\r\n");


            string call_id_num = string(msg->call_id->number);
            string call_header = string("Call-ID: ")+call_id_num+("\r\n");

            string cseq_num = string(msg->cseq->number);
            string cseq_header = string("Cseq: ")+cseq_num+string(" MESSAGE\r\n");
            string content_type_header = "Content-Type: APPLICATION/SDP\r\n";

            string forwords = string("Max-Forwards: 70\r\n");
            string expires = string("Expires: 3000\r\n");
            string contentlenth = string("Content-Length: 0")+string("\r\n");
            string cflr = string("\r\n");

            string sip_msg_str = head_line + via_header + to_header + from_header
                + call_header + cseq_header  + content_type_header + 
                forwords + expires + contentlenth + cflr;
            
#ifdef DEBUG
            cout<<"check 200ok camerainfoack:"<<endl;
            cout<<sip_msg_str<<endl;
#endif
            size_t sip_len = sip_msg_str.length();
            char* sip_msg_c = (char*)malloc(sizeof(char)* sip_len);
            memcpy( sip_msg_c, sip_msg_str.c_str(), sip_len);
            *rtmsg = sip_msg_c;
            *rtlen = sip_len;
            /*send 200ok, wait ack*/
            return;
        }
Beispiel #3
0
int
main (int argc, char **argv)
{
  FILE *vias_file;


  osip_via_t *via;
  char *a_via;
  char *dest;
  char *res;

  vias_file = fopen (argv[1], "r");
  if (vias_file == NULL)
    {
      fprintf (stdout, "Failed to open %s file.\nUsage: tvia vias.txt\n", argv[1]);
      exit (0);
    }

  a_via = (char *) osip_malloc (200);
  res = fgets (a_via, 200, vias_file);  /* lines are under 200 */
  while (res != NULL)
    {

      int errcode;

      /* remove the last '\n' before parsing */
      osip_strncpy (a_via + strlen (a_via) - 1, "\0", 1);

      if (0 != strncmp (a_via, "#", 1))
        {
          /* allocate & init via */
          osip_via_init (&via);
          printf ("=================================================\n");
          printf ("VIA TO PARSE: |%s|\n", a_via);
          errcode = osip_via_parse (via, a_via);
          if (errcode != -1)
            {
              if (osip_via_to_str (via, &dest) != -1)
                {
                  printf ("result:       |%s|\n", dest);
                  osip_free (dest);
                }
          } else
            printf ("Bad via format: %s\n", a_via);
          osip_via_free (via);
          printf ("=================================================\n");
        }
      res = fgets (a_via, 200, vias_file);      /* lines are under 200 */
    }
  osip_free (a_via);

  return 0;
}
Beispiel #4
0
/*
 * create a reply template from an given SIP request
 *
 * RETURNS a pointer to osip_message_t
 */
osip_message_t *msg_make_template_reply (sip_ticket_t *ticket, int code) {
   osip_message_t *request=ticket->sipmsg;
   osip_message_t *response;
   int pos;

   osip_message_init (&response);
   response->message=NULL;
   osip_message_set_version (response, osip_strdup ("SIP/2.0"));
   osip_message_set_status_code (response, code);
   osip_message_set_reason_phrase (response, 
                                   osip_strdup(osip_message_get_reason (code)));

   if (request->to==NULL) {
      ERROR("msg_make_template_reply: empty To in request header");
      return NULL;
   }

   if (request->from==NULL) {
      ERROR("msg_make_template_reply: empty From in request header");
      return NULL;
   }

   osip_to_clone (request->to, &response->to);
   osip_from_clone (request->from, &response->from);

   /* if 3xx, also include 1st contact header */
   if ((code==200) || ((code>=300) && (code<400))) {
      osip_contact_t *req_contact = NULL;
      osip_contact_t *res_contact = NULL;
      osip_message_get_contact(request, 0, &req_contact);
      if (req_contact) osip_contact_clone (req_contact, &res_contact);
      if (res_contact) osip_list_add(response->contacts,res_contact,0);
   }

   /* via headers */
   pos = 0;
   while (!osip_list_eol (request->vias, pos)) {
      char *tmp;
      osip_via_t *via;
      via = (osip_via_t *) osip_list_get (request->vias, pos);
      osip_via_to_str (via, &tmp);

      osip_message_set_via (response, tmp);
      osip_free (tmp);
      pos++;
   }

   osip_call_id_clone(request->call_id,&response->call_id);
   
   osip_cseq_clone(request->cseq,&response->cseq);

   return response;
}
Beispiel #5
0
osip_message_t* init_sip_msg_from_src (const osip_message_t *sipmsg, const int code)
{
    __tri(init_sip_msg_from_src);

    if (sipmsg->to && sipmsg->from)
    {
       osip_message_t* sipgen;
       osip_message_init (&sipgen);

       if (sipgen)
       {
           sipgen->message = NULL;
           osip_message_set_version (sipgen, osip_strdup ("SIP/2.0"));
           osip_message_set_status_code (sipgen, code);
           osip_message_set_reason_phrase (sipgen,
                                   osip_strdup(osip_message_get_reason (code)));


           if (code == SIP_MOVED_TEMPORARILY)
           {
               char contact[100];
                snprintf (contact, sizeof(contact), "<sip:%s@%s:%s>",
                          sipmsg->to->url->username, "sip.voipcheap.com", "5060");

                osip_message_set_contact(sipgen, contact);

                osip_to_clone   (sipmsg->to,   &sipgen->from);
                osip_from_clone (sipmsg->from, &sipgen->to);

           }
           else
           {
               /*include 1st contact header  if 3xx*/
               if (code < SIP_BAD_REQUEST && (SIP_OK == code || code >= SIP_MULTIPLE_CHOICES) )
               {
                   osip_contact_t* src_contact = NULL;
                   osip_message_get_contact(sipmsg, 0, &src_contact);

                   if (src_contact)
                   {
                       osip_contact_t* res_contact = NULL;
                       osip_contact_clone (src_contact, &res_contact);

                       if (res_contact)
                       {
                           osip_list_add(&(sipgen->contacts),res_contact,0);
                       }
                   }
               }

               osip_to_clone   (sipmsg->to,   &sipgen->to);
               osip_from_clone (sipmsg->from, &sipgen->from);
           }

           /* via headers */
           int pos = 0;
           while (!osip_list_eol (&sipmsg->vias, pos))
           {
               osip_via_t*via = (osip_via_t*)osip_list_get (&sipmsg->vias, pos);
               char *tmp;
               osip_via_to_str (via, &tmp);
               osip_message_set_via (sipgen, tmp);
               osip_free (tmp);
               pos++;
           }

           osip_call_id_clone (sipmsg->call_id, &sipgen->call_id);
           osip_cseq_clone    (sipmsg->cseq,    &sipgen->cseq);
           __tre(return) sipgen;
       }
   }
Beispiel #6
0
        void SIPBuilder::BeenInvited( osip_message_t* msg, string port,char** rtmsg,
                size_t *rtlen, int*state, struct DialogInfo &dlg_info)
        {
            string uac_ip = _local_ip_str_;
            string uac_listen_port_str = _local_port_str_;
            string local_dev_name = _dev_name_;

            string head_line("SIP/2.0 200 OK\r\n");

            osip_via_t *via;
            char* via_c = NULL; 
            if( !osip_list_eol (&msg->vias, 0))
            {
                via = (osip_via_t *) osip_list_get (&msg->vias, 0);
                osip_via_to_str( via, &via_c);
            }else{
                *state = -1;
                return;
            }
            string via_header(via_c);
            via_header = string("Via: ")+via_header+string("\r\n");
            
            char* from_tag_c;
            osip_from_to_str( msg->from, &from_tag_c );
            string from_header(from_tag_c);
            from_header = string("From: ")+from_header+string("\r\n");

            char* to_tag_c;
            osip_to_to_str( msg->to, &to_tag_c );
            string to_header(to_tag_c);
            string to_tag_num = _RandomNum();
            to_header = to_header + ";tag="+to_tag_num;
            to_header = string("To: ")+to_header+string("\r\n");
            dlg_info.to_tag_num = to_tag_num;

            string contact_header;
            stringstream stream_contact_header;
            stream_contact_header<<"Contact: <sip:" << local_dev_name << "@" << uac_ip << ":"<< uac_listen_port_str<<">\r\n";
            contact_header = stream_contact_header.str();

            string call_id_num = string(msg->call_id->number);
            string call_header = string("Call-ID: ")+call_id_num+("\r\n");

            string cseq_num = string(msg->cseq->number);
            string cseq_header = string("Cseq: ")+cseq_num+string(" INVITE\r\n");
            string content_type_header = "Content-Type: APPLICATION/SDP\r\n";

            string forwords = string("Max-Forwards: 70\r\n");
            string expires = string("Expires: 3000\r\n");
            string sdp_msg = _sdp_builder_.toString( string("##2015"), port);
            stringstream sdp_msg_length; 
            sdp_msg_length<< sdp_msg.length();
            string contentlenth = string("Content-Length: ")+sdp_msg_length.str()+string("\r\n");
            string cflr = string("\r\n");

            string sip_msg_str = head_line + via_header + to_header + from_header
                + call_header + cseq_header  + contact_header  +  content_type_header + 
                forwords + expires + contentlenth + cflr + sdp_msg;
#ifdef DEBUG
            cout<<"check Been Invite:"<<endl;
            cout<<sip_msg_str<<endl;
#endif
            size_t sip_len = sip_msg_str.length();
            char* sip_msg_c = (char*)malloc(sizeof(char)* sip_len);
            memcpy( sip_msg_c, sip_msg_str.c_str(), sip_len);
            *rtmsg = sip_msg_c;
            *rtlen = sip_len;
            /*send 200ok, wait ack*/
            *state = 0;
            return;
        }
Beispiel #7
0
/*
 * SIP_CALCULATE_BRANCH
 *
 * Calculates a branch parameter according to RFC3261 section 16.11
 *
 * The returned 'id' will be HASHHEXLEN + strlen(magic_cookie)
 * characters (32 + 7) long. The caller must supply at least this
 * amount of space in 'id'.
 *
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 */
int  sip_calculate_branch_id (sip_ticket_t *ticket, char *id) {
/* RFC3261 section 16.11 recommends the following procedure:
 *   The stateless proxy MAY use any technique it likes to guarantee
 *   uniqueness of its branch IDs across transactions.  However, the
 *   following procedure is RECOMMENDED.  The proxy examines the
 *   branch ID in the topmost Via header field of the received
 *   request.  If it begins with the magic cookie, the first
 *   component of the branch ID of the outgoing request is computed
 *   as a hash of the received branch ID.  Otherwise, the first
 *   component of the branch ID is computed as a hash of the topmost
 *   Via, the tag in the To header field, the tag in the From header
 *   field, the Call-ID header field, the CSeq number (but not
 *   method), and the Request-URI from the received request.  One of
 *   these fields will always vary across two different
 *   transactions.
 *
 * The branch value will consist of:
 * - magic cookie "z9hG4bK"
 * - 1st part (unique calculated ID
 * - 2nd part (value for loop detection) <<- not yet used by siproxd
 */
   osip_message_t *sip_msg=ticket->sipmsg;
   static char *magic_cookie="z9hG4bK";
   osip_via_t *via;
   osip_uri_param_t *param=NULL;
   osip_call_id_t *call_id=NULL;
   HASHHEX hashstring;

   hashstring[0]='\0';

   /*
    * Examine topmost via and look for a magic cookie.
    * If it is there, I use THIS branch parameter as input for
    * our hash calculation
    */
   via = osip_list_get (sip_msg->vias, 0);
   if (via == NULL) {
      ERROR("have a SIP message without any via header");
      return STS_FAILURE;
   }

   param=NULL;
   osip_via_param_get_byname(via, "branch", &param);
   if (param && param->gvalue) {
      DEBUGC(DBCLASS_BABBLE, "looking for magic cookie [%s]",param->gvalue);
      if (strncmp(param->gvalue, magic_cookie,
                  strlen(magic_cookie))==0) {
         /* calculate MD5 hash */
         MD5_CTX Md5Ctx;
         HASH HA1;

         MD5Init(&Md5Ctx);
         MD5Update(&Md5Ctx, param->gvalue,
                   strlen(param->gvalue));
         MD5Final(HA1, &Md5Ctx);
         CvtHex(HA1, hashstring);

         DEBUGC(DBCLASS_BABBLE, "existing branch -> branch hash [%s]",
                hashstring);
      }
   }

   /*
    * If I don't have a branch parameter in the existing topmost via,
    * then I need:
    *   - the topmost via
    *   - the tag in the To header field
    *   - the tag in the From header field
    *   - the Call-ID header field
    *   - the CSeq number (but not method)
    *   - the Request-URI from the received request
    */
   if (hashstring[0] == '\0') {
      /* calculate MD5 hash */
      MD5_CTX Md5Ctx;
      HASH HA1;
      char *tmp;

      MD5Init(&Md5Ctx);

      /* topmost via */
      osip_via_to_str(via, &tmp);
      if (tmp) {
         MD5Update(&Md5Ctx, tmp, strlen(tmp));
         osip_free(tmp);
      }
     
      /* Tag in To header */
      osip_to_get_tag(sip_msg->to, &param);
      if (param && param->gvalue) {
         MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue));
      }

      /* Tag in From header */
      osip_from_get_tag(sip_msg->from, &param);
      if (param && param->gvalue) {
         MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue));
      }

      /* Call-ID */
      call_id = osip_message_get_call_id(sip_msg);
      osip_call_id_to_str(call_id, &tmp);
      if (tmp) {
         MD5Update(&Md5Ctx, tmp, strlen(tmp));
         osip_free(tmp);
      }

      /* CSeq number (but not method) */
      tmp = osip_cseq_get_number(sip_msg->cseq);
      if (tmp) {
         MD5Update(&Md5Ctx, tmp, strlen(tmp));
      }
 
      /* Request URI */
      osip_uri_to_str(sip_msg->req_uri, &tmp);
      if (tmp) {
         MD5Update(&Md5Ctx, tmp, strlen(tmp));
         osip_free(tmp);
      }

      MD5Final(HA1, &Md5Ctx);
      CvtHex(HA1, hashstring);

      DEBUGC(DBCLASS_BABBLE, "non-existing branch -> branch hash [%s]",
             hashstring);
   }

   /* include the magic cookie */
   sprintf(id, "%s%s", magic_cookie, hashstring);

   return STS_SUCCESS;
}