Пример #1
0
static int
ac_packetfilter_simple(ac_sip_t *asip, void *data)
{
	osip_message_t* sip = asip->req->evt->sip;
	int code = osip_message_get_status_code(sip);

	LOG_DEBUG("Performing simple ac on %s->%s, remote: %d\n", asip->from, asip->to, asip->req->remote_msg);
	/* filter only inbound */
	if (asip->req->remote_msg && !asip->req->internally_generated) {
		
		/* todo: we should check that the sip from == the aor
		   associated with the connection (on remote calls) */

		/* except that that would mess up the gateway things. */

		//ASSERT_ZERO(sipp_get_sip_aors_simple(sip, &local_aor, &remote_aor, 1), end);
		/*
		if ((!MSG_IS_RESPONSE(asip->evt->sip) &&
		     (strcmp(asip->from, asip->remote) || strcmp(asip->to, asip->local))) ||
		    (MSG_IS_RESPONSE(asip->evt->sip) &&
		     (strcmp(asip->to, asip->remote) || strcmp(asip->from, asip->local))))
			asip->verdict = AC_VERDICT_REJECT;
		else 
		*/
		if (MSG_IS_RESPONSE(sip)) {

			/* reject 482 merges, as server loops aren't of any interest to us */
			if (code == 482) {
				LOG_WARN("Skipping %d response\n", code);
				asip->verdict = AC_VERDICT_REJECT;
			}
		} else if (MSG_IS_ACK(sip) || MSG_IS_BYE(sip) || MSG_IS_CANCEL(sip) || MSG_IS_UPDATE(sip)) {
			
			/* this we should let through pretty much undisturbed */
		
		} else if (MSG_IS_SUBSCRIBE(sip) || MSG_IS_PUBLISH(sip)) {

			/* if this is remotely got, just reject */
			asip->verdict = AC_VERDICT_REJECT;

		} else if (MSG_IS_INVITE(sip) || MSG_IS_MESSAGE(sip)) {
			/* hm, nothing.. */
			// } else if (MSG_IS_NOTIFY(sip)) {
			
		} else {
			/* todo: what about OPTIONS? */
			LOG_WARN("Got unsupported request\n");
			asip->verdict = AC_VERDICT_UNSUPP;
		}
	} else {
		/* allow *all* outgoing! */
		asip->verdict = AC_VERDICT_ALLOW;
	}

	return 1;
}
Пример #2
0
void
nict_snd_request (osip_transaction_t * nict, osip_event_t * evt)
{
  int i;
  osip_t *osip = (osip_t *) nict->config;

  /* Here we have ict->orig_request == NULL */
  nict->orig_request = evt->sip;

  i = osip->cb_send_message (nict, evt->sip, nict->nict_context->destination,
                             nict->nict_context->port, nict->out_socket);

  if (i == 0)
    {
      /* invoke the right callback! */
      if (MSG_IS_REGISTER (evt->sip))
        __osip_message_callback (OSIP_NICT_REGISTER_SENT, nict,
                                 nict->orig_request);
      else if (MSG_IS_BYE (evt->sip))
        __osip_message_callback (OSIP_NICT_BYE_SENT, nict, nict->orig_request);
      else if (MSG_IS_OPTIONS (evt->sip))
        __osip_message_callback (OSIP_NICT_OPTIONS_SENT, nict, nict->orig_request);
      else if (MSG_IS_INFO (evt->sip))
        __osip_message_callback (OSIP_NICT_INFO_SENT, nict, nict->orig_request);
      else if (MSG_IS_CANCEL (evt->sip))
        __osip_message_callback (OSIP_NICT_CANCEL_SENT, nict, nict->orig_request);
      else if (MSG_IS_NOTIFY (evt->sip))
        __osip_message_callback (OSIP_NICT_NOTIFY_SENT, nict, nict->orig_request);
      else if (MSG_IS_SUBSCRIBE (evt->sip))
        __osip_message_callback (OSIP_NICT_SUBSCRIBE_SENT, nict,
                                 nict->orig_request);
      else
        __osip_message_callback (OSIP_NICT_UNKNOWN_REQUEST_SENT, nict,
                                 nict->orig_request);
      __osip_transaction_set_state (nict, NICT_TRYING);
  } else
    {
      nict_handle_transport_error (nict, i);
    }
}
Пример #3
0
void
nist_rcv_request (osip_transaction_t * nist, osip_event_t * evt)
{
  int i;

  if (nist->state == NIST_PRE_TRYING)   /* announce new REQUEST */
    {
      /* Here we have ist->orig_request == NULL */
      nist->orig_request = evt->sip;

      if (MSG_IS_REGISTER (evt->sip))
        __osip_message_callback (OSIP_NIST_REGISTER_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_BYE (evt->sip))
        __osip_message_callback (OSIP_NIST_BYE_RECEIVED, nist, nist->orig_request);
      else if (MSG_IS_OPTIONS (evt->sip))
        __osip_message_callback (OSIP_NIST_OPTIONS_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_INFO (evt->sip))
        __osip_message_callback (OSIP_NIST_INFO_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_CANCEL (evt->sip))
        __osip_message_callback (OSIP_NIST_CANCEL_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_NOTIFY (evt->sip))
        __osip_message_callback (OSIP_NIST_NOTIFY_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_SUBSCRIBE (evt->sip))
        __osip_message_callback (OSIP_NIST_SUBSCRIBE_RECEIVED, nist,
                                 nist->orig_request);
      else
        __osip_message_callback (OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, nist,
                                 nist->orig_request);
  } else                        /* NIST_PROCEEDING or NIST_COMPLETED */
    {
      /* delete retransmission */
      osip_message_free (evt->sip);

      __osip_message_callback (OSIP_NIST_REQUEST_RECEIVED_AGAIN, nist,
                               nist->orig_request);
      if (nist->last_response != NULL)  /* retransmit last response */
        {
	  i = __osip_transaction_snd_xxx(nist, nist->last_response);
          if (i != 0)
            {
              nist_handle_transport_error (nist, i);
              return;
          } else
            {
              if (MSG_IS_STATUS_1XX (nist->last_response))
                __osip_message_callback (OSIP_NIST_STATUS_1XX_SENT, nist,
                                         nist->last_response);
              else if (MSG_IS_STATUS_2XX (nist->last_response))
                __osip_message_callback (OSIP_NIST_STATUS_2XX_SENT_AGAIN,
                                         nist, nist->last_response);
              else
                __osip_message_callback (OSIP_NIST_STATUS_3456XX_SENT_AGAIN,
                                         nist, nist->last_response);
              return;
            }
        }
      /* we are already in the proper state */
      return;
    }

  /* we come here only if it was the first REQUEST received */
  __osip_transaction_set_state (nist, NIST_TRYING);
}
Пример #4
0
/*
 * PROXY_REQUEST
 *
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 *
 * RFC3261
 *    Section 16.3: Proxy Behavior - Request Validation
 *    1. Reasonable Syntax
 *    2. URI scheme
 *    3. Max-Forwards
 *    4. (Optional) Loop Detection
 *    5. Proxy-Require
 *    6. Proxy-Authorization
 *
 *    Section 16.6: Proxy Behavior - Request Forwarding
 *    1.  Make a copy of the received request
 *    2.  Update the Request-URI
 *    3.  Update the Max-Forwards header field
 *    4.  Optionally add a Record-route header field value
 *    5.  Optionally add additional header fields
 *    6.  Postprocess routing information
 *    7.  Determine the next-hop address, port, and transport
 *    8.  Add a Via header field value
 *    9.  Add a Content-Length header field if necessary
 *    10. Forward the new request
 *    11. Set timer C
 */
int proxy_request (sip_ticket_t *ticket) {
   int i;
   int sts;
   int type;
   struct in_addr sendto_addr;
   osip_uri_t *url;
   int port;
   char *buffer;
   int buflen;
   osip_message_t *request;
   struct sockaddr_in *from;

   DEBUGC(DBCLASS_PROXY,"proxy_request");

   if (ticket==NULL) {
      ERROR("proxy_request: called with NULL ticket");
      return STS_FAILURE;
   }

   request=ticket->sipmsg;
   from=&ticket->from;

   /*
    * RFC 3261, Section 16.4
    * Proxy Behavior - Route Information Preprocessing
    * (process Route header)
    */
   route_preprocess(ticket);

   /*
    * figure out whether this is an incoming or outgoing request
    * by doing a lookup in the registration table.
    */
#define _OLD_DIRECTION_EVALUATION 0
#if _OLD_DIRECTION_EVALUATION
   type = 0;
   for (i=0; i<URLMAP_SIZE; i++) {
      if (urlmap[i].active == 0) continue;

      /* incoming request ('to' == 'masq') || (('to' == 'reg') && !REGISTER)*/
      if ((compare_url(request->to->url, urlmap[i].masq_url)==STS_SUCCESS) ||
          (!MSG_IS_REGISTER(request) &&
           (compare_url(request->to->url, urlmap[i].reg_url)==STS_SUCCESS))) {
         type=REQTYP_INCOMING;
         DEBUGC(DBCLASS_PROXY,"incoming request from %s@%s from outbound",
	   request->from->url->username? request->from->url->username:"******",
           request->from->url->host? request->from->url->host: "*NULL*");
	 break;
      }

      /* outgoing request ('from' == 'reg') */
      if (compare_url(request->from->url, urlmap[i].reg_url)==STS_SUCCESS) {
         type=REQTYP_OUTGOING;
         DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",
	   request->from->url->username? request->from->url->username:"******",
           request->from->url->host? request->from->url->host: "*NULL*");
	 break;
      }
   }
#else
   type = 0;
   /*
    * did I receive the telegram from a REGISTERED host?
    * -> it must be an OUTGOING request
    */
   for (i=0; i<URLMAP_SIZE; i++) {
      struct in_addr tmp_addr;

      if (urlmap[i].active == 0) continue;
      if (get_ip_by_host(urlmap[i].true_url->host, &tmp_addr) == STS_FAILURE) {
         DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve host [%s]",
             urlmap[i].true_url);
      } else {
         DEBUGC(DBCLASS_PROXY, "proxy_request: reghost:%s ip:%s",
                urlmap[i].true_url->host, utils_inet_ntoa(from->sin_addr));
         if (memcmp(&tmp_addr, &from->sin_addr, sizeof(tmp_addr)) == 0) {
            type=REQTYP_OUTGOING;
	    break;
         }
      }
   }

   /*
    * is the telegram directed to an internally registered host?
    * -> it must be an INCOMING request
    */
   if (type == 0) {
      for (i=0; i<URLMAP_SIZE; i++) {
         if (urlmap[i].active == 0) continue;
         /* RFC3261:
          * 'To' contains a display name (Bob) and a SIP or SIPS URI
          * (sip:[email protected]) towards which the request was originally
          * directed.  Display names are described in RFC 2822 [3].
          */

         /* So this means, that we must check the SIP URI supplied with the
          * INVITE method, as this points to the real wanted target.
          * Q: does there exist a situation where the SIP URI itself does
          *    point to "somewhere" but the To: points to the correct UA?
          * So for now, we just look at both of them (SIP URI and To: header)
          */

         /* incoming request (SIP URI == 'masq') || ((SIP URI == 'reg') && !REGISTER)*/
         if ((compare_url(request->req_uri, urlmap[i].masq_url)==STS_SUCCESS) ||
             (!MSG_IS_REGISTER(request) &&
              (compare_url(request->req_uri, urlmap[i].reg_url)==STS_SUCCESS))) {
            type=REQTYP_INCOMING;
	    break;
         }
         /* incoming request ('to' == 'masq') || (('to' == 'reg') && !REGISTER)*/
         if ((compare_url(request->to->url, urlmap[i].masq_url)==STS_SUCCESS) ||
             (!MSG_IS_REGISTER(request) &&
              (compare_url(request->to->url, urlmap[i].reg_url)==STS_SUCCESS))) {
            type=REQTYP_INCOMING;
	    break;
         }
      }
   }
#endif
   ticket->direction=type;

   /*
    * logging of passing calls
    */
   if (configuration.log_calls) {
      osip_uri_t *cont_url = NULL;
      if (!osip_list_eol(request->contacts, 0))
         cont_url = ((osip_contact_t*)(request->contacts->node->element))->url;
      
      /* INVITE */
      if (MSG_IS_INVITE(request)) {
         if (cont_url) {
            INFO("%s Call from: %s@%s",
                 (type==REQTYP_INCOMING) ? "Incoming":"Outgoing",
                 cont_url->username ? cont_url->username:"******",
                 cont_url->host ? cont_url->host : "*NULL*");
         } else {
            INFO("%s Call (w/o contact header) from: %s@%s",
                 (type==REQTYP_INCOMING) ? "Incoming":"Outgoing",
	         request->from->url->username ? 
                    request->from->url->username:"******",
	         request->from->url->host ? 
                    request->from->url->host : "*NULL*");
         }
      /* BYE / CANCEL */
      } else if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
         if (cont_url) {
            INFO("Ending Call from: %s@%s",
                 cont_url->username ? cont_url->username:"******",
                 cont_url->host ? cont_url->host : "*NULL*");
         } else {
            INFO("Ending Call (w/o contact header) from: %s@%s",
	         request->from->url->username ? 
                    request->from->url->username:"******",
	         request->from->url->host ? 
                    request->from->url->host : "*NULL*");
         }
      }
   } /* log_calls */


   /*
    * RFC 3261, Section 16.6 step 1
    * Proxy Behavior - Request Forwarding - Make a copy
    */
   /* nothing to do here, copy is ready in 'request'*/

   /* get destination address */
   url=osip_message_get_uri(request);

   switch (type) {
  /*
   * from an external host to the internal masqueraded host
   */
   case REQTYP_INCOMING:
      DEBUGC(DBCLASS_PROXY,"incoming request from %s@%s from outbound",
	request->from->url->username? request->from->url->username:"******",
        request->from->url->host? request->from->url->host: "*NULL*");

      /*
       * RFC 3261, Section 16.6 step 2
       * Proxy Behavior - Request Forwarding - Request-URI
       * (rewrite request URI to point to the real host)
       */
      /* 'i' still holds the valid index into the URLMAP table */
      if (check_rewrite_rq_uri(request) == STS_TRUE) {
         proxy_rewrite_request_uri(request, i);
      }

      /* if this is CANCEL/BYE request, stop RTP proxying */
      if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
         /* stop the RTP proxying stream(s) */
         rtp_stop_fwd(osip_message_get_call_id(request), DIR_INCOMING);
         rtp_stop_fwd(osip_message_get_call_id(request), DIR_OUTGOING);

      /* check for incoming request */
      } else if (MSG_IS_INVITE(request)) {
         /* Rewrite the body */
         sts = proxy_rewrite_invitation_body(request, DIR_INCOMING);

      } else if (MSG_IS_ACK(request)) {
         /* Rewrite the body */
         sts = proxy_rewrite_invitation_body(request, DIR_INCOMING);

      }
      break;
   
  /*
   * from the internal masqueraded host to an external host
   */
   case REQTYP_OUTGOING:
      DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",
	request->from->url->username? request->from->url->username:"******",
        request->from->url->host? request->from->url->host: "*NULL*");

      /*
       * RFC 3261, Section 16.6 step 2
       * Proxy Behavior - Request Forwarding - Request-URI
       */
      /* nothing to do for an outgoing request */


      /* if it is addressed to myself, then it must be some request
       * method that I as a proxy do not support. Reject */
#if 0
/* careful - an internal UA might send an request to another internal UA.
   This would be caught here, so don't do this. This situation should be
   caught in the default part of the CASE statement below */
      if (is_sipuri_local(ticket) == STS_TRUE) {
         WARN("unsupported request [%s] directed to proxy from %s@%s -> %s@%s",
	    request->sip_method? request->sip_method:"*NULL*",
	    request->from->url->username? request->from->url->username:"******",
	    request->from->url->host? request->from->url->host : "*NULL*",
	    url->username? url->username : "******",
	    url->host? url->host : "*NULL*");

         sip_gen_response(ticket, 403 /*forbidden*/);

         return STS_FAILURE;
      }
#endif

      /* rewrite Contact header to represent the masqued address */
      sip_rewrite_contact(ticket, DIR_OUTGOING);

      /* if an INVITE, rewrite body */
      if (MSG_IS_INVITE(request)) {
         sts = proxy_rewrite_invitation_body(request, DIR_OUTGOING);
      } else if (MSG_IS_ACK(request)) {
         sts = proxy_rewrite_invitation_body(request, DIR_OUTGOING);
      }

      /* if this is CANCEL/BYE request, stop RTP proxying */
      if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
         /* stop the RTP proxying stream(s) */
         rtp_stop_fwd(osip_message_get_call_id(request), DIR_INCOMING);
         rtp_stop_fwd(osip_message_get_call_id(request), DIR_OUTGOING);
      }

      break;
   
   default:
      DEBUGC(DBCLASS_PROXY, "request [%s] from/to unregistered UA "
           "(RQ: %s@%s -> %s@%s)",
           request->sip_method? request->sip_method:"*NULL*",
	   request->from->url->username? request->from->url->username:"******",
	   request->from->url->host? request->from->url->host : "*NULL*",
	   url->username? url->username : "******",
	   url->host? url->host : "*NULL*");

/*
 * we may end up here for two reasons:
 *  1) An incomming request (from outbound) that is directed to
 *     an unknown (not registered) local UA
 *  2) an outgoing request from a local UA that is not registered.
 *
 * Case 1) we should probably answer with "404 Not Found",
 * case 2) more likely a "403 Forbidden"
 * 
 * How about "408 Request Timeout" ?
 *
 */
      sip_gen_response(ticket, 408 /* Request Timeout */);

      return STS_FAILURE;
   }


   /*
    * RFC 3261, Section 16.6 step 3
    * Proxy Behavior - Request Forwarding - Max-Forwards
    * (if Max-Forwards header exists, decrement by one, if it does not
    * exist, add a new one with value SHOULD be 70)
    */
   {
   osip_header_t *max_forwards;
   int forwards_count = DEFAULT_MAXFWD;
   char mfwd[8];

   osip_message_get_max_forwards(request, 0, &max_forwards);
   if (max_forwards == NULL) {
      sprintf(mfwd, "%i", forwards_count);
      osip_message_set_max_forwards(request, mfwd);
   } else {
      if (max_forwards->hvalue) {
         forwards_count = atoi(max_forwards->hvalue);
         forwards_count -=1;
         osip_free (max_forwards->hvalue);
      }

      sprintf(mfwd, "%i", forwards_count);
      max_forwards->hvalue = osip_strdup(mfwd);
   }

   DEBUGC(DBCLASS_PROXY,"setting Max-Forwards=%s",mfwd);
   }

   /*
    * RFC 3261, Section 16.6 step 4
    * Proxy Behavior - Request Forwarding - Add a Record-route header
    */

   /*
    * for ALL incoming requests, include my Record-Route header.
    * The local UA will probably send its answer to the topmost 
    * Route Header (8.1.2 of RFC3261)
    */
   if (type == REQTYP_INCOMING) {
      DEBUGC(DBCLASS_PROXY,"Adding my Record-Route");
      route_add_recordroute(ticket);
   } else {
      /*
       * outgoing packets must not have my record route header, as
       * this likely will contain a private IP address (my inbound).
       */
      DEBUGC(DBCLASS_PROXY,"Purging Record-Routes (outgoing packet)");
      route_purge_recordroute(ticket);
   }

   /*
    * RFC 3261, Section 16.6 step 5
    * Proxy Behavior - Request Forwarding - Add Additional Header Fields
    */
   /* NOT IMPLEMENTED (optional) */


   /*
    * RFC 3261, Section 16.6 step 6
    * Proxy Behavior - Request Forwarding - Postprocess routing information
    *
    * If the copy contains a Route header field, the proxy MUST
    * inspect the URI in its first value.  If that URI does not
    * contain an lr parameter, the proxy MUST modify the copy as
    * follows:
    *
    * -  The proxy MUST place the Request-URI into the Route header
    *    field as the last value.
    *
    * -  The proxy MUST then place the first Route header field value
    *    into the Request-URI and remove that value from the Route
    *    header field.
    */
#if 0
   route_postprocess(ticket);
#endif

   /*
    * RFC 3261, Section 16.6 step 7
    * Proxy Behavior - Determine Next-Hop Address
    */
/*&&&& priority probably should be:
 * 1) Route header
 * 2) fixed outbound proxy
 * 3) SIP URI
 */
   /*
    * fixed or domain outbound proxy defined ?
    */
   if ((type == REQTYP_OUTGOING) &&
       (sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
      DEBUGC(DBCLASS_PROXY, "proxy_request: have outbound proxy %s:%i",
             utils_inet_ntoa(sendto_addr), port);
   /*
    * Route present?
    * If so, fetch address from topmost Route: header and remove it.
    */
   } else if ((type == REQTYP_OUTGOING) && 
              (request->routes && !osip_list_eol(request->routes, 0))) {
      sts=route_determine_nexthop(ticket, &sendto_addr, &port);
      if (sts == STS_FAILURE) {
         DEBUGC(DBCLASS_PROXY, "proxy_request: route_determine_nexthop failed");
         return STS_FAILURE;
      }
      DEBUGC(DBCLASS_PROXY, "proxy_request: have Route header to %s:%i",
             utils_inet_ntoa(sendto_addr), port);
   /*
    * destination from SIP URI
    */
   } else {
      /* get the destination from the SIP URI */
      sts = get_ip_by_host(url->host, &sendto_addr);
      if (sts == STS_FAILURE) {
         DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve URI [%s]",
                url->host);
         return STS_FAILURE;
      }

      if (url->port) {
         port=atoi(url->port);
      } else {
         port=SIP_PORT;
      }
      DEBUGC(DBCLASS_PROXY, "proxy_request: have SIP URI to %s:%i",
             url->host, port);
   }

   /*
    * RFC 3261, Section 16.6 step 8
    * Proxy Behavior - Add a Via header field value
    */
   /* add my Via header line (outbound interface)*/
   if (type == REQTYP_INCOMING) {
      sts = sip_add_myvia(ticket, IF_INBOUND);
      if (sts == STS_FAILURE) {
         ERROR("adding my inbound via failed!");
      }
   } else {
      sts = sip_add_myvia(ticket, IF_OUTBOUND);
      if (sts == STS_FAILURE) {
         ERROR("adding my outbound via failed!");
         return STS_FAILURE;
      }
   }
  /*
   * RFC 3261, Section 16.6 step 9
   * Proxy Behavior - Add a Content-Length header field if necessary
   */
  /* not necessary, already in message and we do not support TCP */

  /*
   * RFC 3261, Section 16.6 step 10
   * Proxy Behavior - Forward the new request
   */
   sts = sip_message_to_str(request, &buffer, &buflen);
   if (sts != 0) {
      ERROR("proxy_request: sip_message_to_str failed");
      return STS_FAILURE;
   }

   sipsock_send(sendto_addr, port, ticket->protocol,
                buffer, buflen); 
   osip_free (buffer);

  /*
   * RFC 3261, Section 16.6 step 11
   * Proxy Behavior - Set timer C
   */
  /* NOT IMPLEMENTED - does this really apply for stateless proxies? */

   return STS_SUCCESS;
}
Пример #5
0
void
nict_snd_request (osip_transaction_t * nict, osip_event_t * evt)
{
  int i;
  osip_t *osip = (osip_t *) nict->config;

  /* Here we have ict->orig_request == NULL */
  nict->orig_request = evt->sip;

  i = osip->cb_send_message (nict, evt->sip, nict->nict_context->destination, nict->nict_context->port, nict->out_socket);

  if (i >= 0) {
    /* invoke the right callback! */
    if (MSG_IS_REGISTER (evt->sip))
      __osip_message_callback (OSIP_NICT_REGISTER_SENT, nict, nict->orig_request);
    else if (MSG_IS_BYE (evt->sip))
      __osip_message_callback (OSIP_NICT_BYE_SENT, nict, nict->orig_request);
    else if (MSG_IS_OPTIONS (evt->sip))
      __osip_message_callback (OSIP_NICT_OPTIONS_SENT, nict, nict->orig_request);
    else if (MSG_IS_INFO (evt->sip))
      __osip_message_callback (OSIP_NICT_INFO_SENT, nict, nict->orig_request);
    else if (MSG_IS_CANCEL (evt->sip))
      __osip_message_callback (OSIP_NICT_CANCEL_SENT, nict, nict->orig_request);
    else if (MSG_IS_NOTIFY (evt->sip))
      __osip_message_callback (OSIP_NICT_NOTIFY_SENT, nict, nict->orig_request);
    else if (MSG_IS_SUBSCRIBE (evt->sip))
      __osip_message_callback (OSIP_NICT_SUBSCRIBE_SENT, nict, nict->orig_request);
    else
      __osip_message_callback (OSIP_NICT_UNKNOWN_REQUEST_SENT, nict, nict->orig_request);
#ifndef USE_BLOCKINGSOCKET
    /*
       stop timer E in reliable transport - non blocking socket: 
       the message was just sent
     */
    {
      osip_via_t *via;
      char *proto;
      int k;
      k = osip_message_get_via (nict->orig_request, 0, &via);   /* get top via */
      if (k < 0) {
        nict_handle_transport_error (nict, -1);
        return;
      }
      proto = via_get_protocol (via);
      if (proto == NULL) {
        nict_handle_transport_error (nict, -1);
        return;
      }
      if (i == 0) {               /* but message was really sent */
        if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) {
        }
        else {                    /* reliable protocol is used: */
          nict->nict_context->timer_e_length = -1;        /* E is not ACTIVE */
          nict->nict_context->timer_e_start.tv_sec = -1;
        }
      } else {
        if (osip_strcasecmp (proto, "TCP") != 0 && osip_strcasecmp (proto, "TLS") != 0 && osip_strcasecmp (proto, "SCTP") != 0) {
        }
        else {                    /* reliable protocol is used: */
          nict->nict_context->timer_e_length = DEFAULT_T1_TCP_PROGRESS;
        }
      }
    }
#endif
    if (nict->nict_context->timer_e_length > 0) {
      osip_gettimeofday (&nict->nict_context->timer_e_start, NULL);
      add_gettimeofday (&nict->nict_context->timer_e_start, nict->nict_context->timer_e_length);
    }
    __osip_transaction_set_state (nict, NICT_TRYING);
  }
  else {
    nict_handle_transport_error (nict, i);
  }
}
Пример #6
0
void
nist_rcv_request (osip_transaction_t * nist, osip_event_t * evt)
{
  int i;
  osip_t *osip = (osip_t *) nist->config;

  if (nist->state == NIST_PRE_TRYING)	/* announce new REQUEST */
    {
      /* Here we have ist->orig_request == NULL */
      nist->orig_request = evt->sip;

      if (MSG_IS_REGISTER (evt->sip))
	__osip_message_callback (OSIP_NIST_REGISTER_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_BYE (evt->sip))
	__osip_message_callback (OSIP_NIST_BYE_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_OPTIONS (evt->sip))
	__osip_message_callback (OSIP_NIST_OPTIONS_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_INFO (evt->sip))
	__osip_message_callback (OSIP_NIST_INFO_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_CANCEL (evt->sip))
	__osip_message_callback (OSIP_NIST_CANCEL_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_NOTIFY (evt->sip))
	__osip_message_callback (OSIP_NIST_NOTIFY_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_SUBSCRIBE (evt->sip))
	__osip_message_callback (OSIP_NIST_SUBSCRIBE_RECEIVED, nist,
			   nist->orig_request);
      else
	__osip_message_callback (OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, nist,
			   nist->orig_request);
    }
  else				/* NIST_PROCEEDING or NIST_COMPLETED */
    {
      /* delete retransmission */
      osip_message_free (evt->sip);

      __osip_message_callback (OSIP_NIST_REQUEST_RECEIVED_AGAIN, nist,
			 nist->orig_request);
      if (nist->last_response != NULL)	/* retransmit last response */
	{
	  osip_via_t *via;

	  via = (osip_via_t *) osip_list_get (nist->last_response->vias, 0);
	  if (via)
	    {
	      char *host;
	      int port;
	      osip_generic_param_t *maddr;
	      osip_generic_param_t *received;
	      osip_generic_param_t *rport;
	      osip_via_param_get_byname (via, "maddr", &maddr);
	      osip_via_param_get_byname (via, "received", &received);
	      osip_via_param_get_byname (via, "rport", &rport);
	      /* 1: user should not use the provided information
	         (host and port) if they are using a reliable
	         transport. Instead, they should use the already
	         open socket attached to this transaction. */
	      /* 2: check maddr and multicast usage */
	      if (maddr != NULL)
		host = maddr->gvalue;
	      /* we should check if this is a multicast address and use
	         set the "ttl" in this case. (this must be done in the
	         UDP message (not at the SIP layer) */
	      else if (received != NULL)
		host = received->gvalue;
	      else
		host = via->host;

	      if (rport == NULL || rport->gvalue == NULL)
		{
		  if (via->port != NULL)
		    port = osip_atoi (via->port);
		  else
		    port = 5060;
		}
	      else
		port = osip_atoi (rport->gvalue);

	      i = osip->cb_send_message (nist, nist->last_response, host,
					 port, nist->out_socket);
	    }
	  else
	    i = -1;
	  if (i != 0)
	    {
              nist_handle_transport_error (nist, i);
	      return;
	    }
	  else
	    {
	      if (MSG_IS_STATUS_1XX (nist->last_response))
		__osip_message_callback (OSIP_NIST_STATUS_1XX_SENT, nist,
				   nist->last_response);
	      else if (MSG_IS_STATUS_2XX (nist->last_response))
		__osip_message_callback (OSIP_NIST_STATUS_2XX_SENT_AGAIN, nist,
				   nist->last_response);
	      else
		__osip_message_callback (OSIP_NIST_STATUS_3456XX_SENT_AGAIN, nist,
				   nist->last_response);
	      return;
	    }
	}
      /* we are already in the proper state */
      return;
    }

  /* we come here only if it was the first REQUEST received */
  __osip_transaction_set_state (nist, NIST_TRYING);
}
Пример #7
0
gint get_exosip_events(gpointer main_window)
{
	eXosip_event_t *je;
	char display[500] = "";
 	eXosip_lock();
	eXosip_unlock();

	/* Check for eXosip event - timeout after 50ms */
	if((je = eXosip_event_wait(0,50)) != NULL)
	{
		/* Uncomment the next line for debugging */
		 //fprintf(stderr, "Event type: %d %s\n", je->type, je->textinfo);

		imsua_display_event_info(je);

		if (je->type == EXOSIP_CALL_INVITE)
		{
			ims_process_incoming_invite(je);
		}
		else if (je->type == EXOSIP_CALL_REINVITE)
		{
			ims_process_incoming_reinvite(je);
		}
		else if (je->type == EXOSIP_CALL_RINGING)
		{
			ims_process_18x(je);
		}
		else if (je->type == EXOSIP_CALL_GLOBALFAILURE)
		{
			ims_process_released_call(je);
		}
		else if (je->type == EXOSIP_CALL_CLOSED)
		{
			ims_process_released_call(je);
		}
		else if (je->type == EXOSIP_CALL_ANSWERED)
		{
			ims_process_200ok(je);

		}
		else if (je->type == EXOSIP_CALL_RELEASED)
		{
			ims_process_released_call(je);

		}
		else if (je->type ==  EXOSIP_CALL_CANCELLED)
		{
		 	ims_process_released_call(je);
		}
		else if (je->type == EXOSIP_CALL_ACK)
		{
			ims_process_ack(je);
		}
		else if (je->type == EXOSIP_CALL_MESSAGE_REQUESTFAILURE)
		{
			ims_process_released_call(je);
		}
		else if (je->type == EXOSIP_CALL_REQUESTFAILURE)
		{
			set_display("Call released");
		}
		else if (je->type == EXOSIP_CALL_SERVERFAILURE)
		{
			set_display("Call released by server");
		}
		else if (je->type == EXOSIP_CALL_MESSAGE_NEW)
		{
			if (MSG_IS_PRACK(je->request))
				ims_process_prack(je);
			else if (MSG_IS_UPDATE(je->request))
				ims_process_update(je);
			else if (MSG_IS_INFO(je->request))
				common_process_info(je);
			else if (MSG_IS_BYE(je->request))
				imsua_set_message_display("OK (BYE)", 1);
		}
		else if (je->type == EXOSIP_CALL_MESSAGE_ANSWERED)
		{
			if (MSG_IS_BYE(je->request))
				ims_process_released_call(je);
			else if (MSG_IS_UPDATE(je->request) || MSG_IS_PRACK(je->request))
				ims_process_2xx(je);
		}
		else if (je->type == EXOSIP_MESSAGE_NEW)
		{
			if (MSG_IS_MESSAGE(je->request))
			{
				/* Checks that message is actually destined for user by comparing sending TO field to IMPU */
				char sending_ui[50];
				strcpy(sending_ui,(((je->request)->to)->url)->username);
				strcat(sending_ui,"@");
				strcat(sending_ui,(((je->request)->to)->url)->host);

				char *temp;
				temp = strstr(pref->impu,":") + 1;

				if(strcmp(sending_ui,temp)==0)
				{
					char *null_string = NULL;
					ims_start_im_session(je, null_string);
				}

			}
			else if (MSG_IS_BYE(je->request))
			{
				set_display("Call ended");
			}

		}
		else if(je->type == EXOSIP_MESSAGE_REQUESTFAILURE)
		{

		}
		else if(je->type == EXOSIP_MESSAGE_ANSWERED)
		{

		}
		else if(je->type == EXOSIP_REGISTRATION_SUCCESS)
		{

			if(is_message_deregister == 1)
			{
				registered = NOT_REGISTERED;

				is_message_deregister = 0;

				sprintf(display, "Deregistered with %s",pref->realm);
				set_display(display);

				sprintf(display,"Not registered");
				set_status_bar(display);

				watchers_remove_all_watchers();

				num_associated_uris = 0;

			}
			else
			{
				registered = REGISTERED;
				ims_process_registration_200ok(je);

			}
		}
		else if(je->type == EXOSIP_REGISTRATION_FAILURE)
		{

			if((je->response)== NULL)
			{
				set_display("Registration failed for unknown reason\nMost probably incorrect credentials\n\nCheck Preferences");
			}
			else if(((je->response)->status_code == 403))
			{
				set_display("Invalid user name\n\nCheck Preferences");
			}
			else if(((je->response)->status_code == 401))
			{
				ims_process_401(je);
			}
			else if(((je->response)->status_code == 404) || ((je->response)->status_code == 407))
			{

				set_display("Error with credentials\n\nCheck Preferences");
			}
			else
			{
				set_display("Registration failed for unknown reason\n\nMost probably incorrect credentials\nCheck Preferences");
			}

		}
		else if(je->type == EXOSIP_REGISTRATION_REFRESHED)
		{
			set_display("Registration Refreshed");
			registered = REGISTERED;
		}
		else if(je->type == EXOSIP_REGISTRATION_TERMINATED)
		{
		}
		else if(je->type == EXOSIP_SUBSCRIPTION_ANSWERED)
		{
			ims_process_subscription_answered(je);
		}
		else if (je->type == EXOSIP_SUBSCRIPTION_NOTIFY)
		{
			ims_process_notify(je);

		}
		else if (je->type == EXOSIP_SUBSCRIPTION_REQUESTFAILURE)
		{

		}
		else if (je->type == EXOSIP_IN_SUBSCRIPTION_NEW)
		{

		}
		else if((je->response)&&((je->response)->status_code == 302))
		{
			ims_process_302(je);
		}
		else
		{
		}

	}

	return TRUE;
}
Пример #8
0
int
_eXosip_complete_answer_that_establish_a_dialog (struct eXosip_t *excontext, osip_message_t * response, osip_message_t * request)
{
  int i;
  int route_found = 0;
  char contact[1024];
  char scheme[10];
  osip_list_iterator_t it;
  osip_record_route_t *rr;

  snprintf(scheme, sizeof(scheme), "sip");

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

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

    /* rfc3261: 12.1.1 UAS behavior (check sips in top most Record-Route) */
    if (it.pos==0 && rr2!=NULL && rr2->url!=NULL && rr2->url->scheme!=NULL && osip_strcasecmp(rr2->url->scheme, "sips")==0)
      snprintf(scheme, sizeof(scheme), "sips");

    rr = (osip_record_route_t *)osip_list_get_next(&it);
    route_found=1;
  }

  if (MSG_IS_BYE (request)) {
    return OSIP_SUCCESS;
  }

  if (route_found==0) {
    /* rfc3261: 12.1.1 UAS behavior (check sips in Contact if no Record-Route) */
    osip_contact_t *co = (osip_contact_t *) osip_list_get(&request->contacts, 0);
    if (co!=NULL && co->url!=NULL && co->url->scheme!=NULL && osip_strcasecmp(co->url->scheme, "sips")==0)
      snprintf(scheme, sizeof(scheme), "sips");
  }
  /* rfc3261: 12.1.1 UAS behavior (check sips in Request-URI) */
  if (request->req_uri->scheme!=NULL && osip_strcasecmp(request->req_uri->scheme, "sips")==0)
    snprintf(scheme, sizeof(scheme), "sips");

  /* special values to be replaced in transport layer (eXtl_*.c files) */
  if (request->to->url->username == NULL)
    snprintf (contact, 1000, "<%s:999.999.999.999:99999>", scheme);
  else {
    char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username);

    snprintf (contact, 1000, "<%s:%[email protected]:99999>", scheme, tmp2);
    osip_free (tmp2);
  }

  {
    osip_via_t *via;

    via = (osip_via_t *) osip_list_get (&response->vias, 0);
    if (via == NULL || via->protocol == NULL)
      return OSIP_SYNTAXERROR;
    if (excontext->enable_outbound==1) {
      contact[strlen (contact) - 1] = '\0';
      strcat (contact, ";ob");
      strcat (contact, ">");
    }
    if (strlen (contact) + strlen (via->protocol) + strlen (";transport=>") < 1024 && 0 != osip_strcasecmp (via->protocol, "UDP")) {
      contact[strlen (contact) - 1] = '\0';
      strcat (contact, ";transport=");
      strcat (contact, via->protocol);
      strcat (contact, ">");
    }
    if (excontext->sip_instance[0] != 0 && strlen (contact) + 64 < 1024) {
      strcat(contact, ";+sip.instance=\"<urn:uuid:");
      strcat(contact, excontext->sip_instance);
      strcat(contact, ">\"");
    }
  }

  osip_message_set_contact (response, contact);

  if (excontext->default_contact_displayname[0]!='\0') {
    osip_contact_t *new_contact;
    osip_message_get_contact(response, 0, &new_contact);
    if (new_contact!=NULL) {
      new_contact->displayname = osip_strdup (excontext->default_contact_displayname);
    }
  }

  if (excontext->eXtl_transport._tl_update_contact!=NULL)
    excontext->eXtl_transport._tl_update_contact(excontext, response);
  return OSIP_SUCCESS;
}
Пример #9
0
int
_eXosip_complete_answer_that_establish_a_dialog (struct eXosip_t *excontext, 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];
  char scheme[10];

  snprintf(scheme, sizeof(scheme), "sip");

  /* 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_record_route_t *) 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);

    /* rfc3261: 12.1.1 UAS behavior (check sips in top most Record-Route) */
    if (pos==0 && rr2!=NULL && rr2->url!=NULL && rr2->url->scheme!=NULL && osip_strcasecmp(rr2->url->scheme, "sips")==0)
      snprintf(scheme, sizeof(scheme), "sips");

    pos++;
  }

  if (MSG_IS_BYE (request)) {
    return OSIP_SUCCESS;
  }

  if (pos==0) {
    /* rfc3261: 12.1.1 UAS behavior (check sips in Contact if no Record-Route) */
    osip_contact_t *co = (osip_contact_t *) osip_list_get(&request->contacts, 0);
    if (pos==0 && co!=NULL && co->url!=NULL && co->url->scheme!=NULL && osip_strcasecmp(co->url->scheme, "sips")==0)
      snprintf(scheme, sizeof(scheme), "sips");
  }
  /* rfc3261: 12.1.1 UAS behavior (check sips in Request-URI) */
  if (request->req_uri->scheme!=NULL && osip_strcasecmp(request->req_uri->scheme, "sips")==0)
    snprintf(scheme, sizeof(scheme), "sips");

  firewall_ip[0] = '\0';
  firewall_port[0] = '\0';
  if (excontext->eXtl_transport.tl_get_masquerade_contact != NULL) {
    excontext->eXtl_transport.tl_get_masquerade_contact (excontext, firewall_ip, sizeof (firewall_ip), firewall_port, sizeof (firewall_port));
  }

  memset (locip, '\0', sizeof (locip));
  _eXosip_guess_ip_for_via (excontext, excontext->eXtl_transport.proto_family, locip, 49);

  if (request->to->url->username == NULL)
    snprintf (contact, 1000, "<%s:%s:%s>", scheme, locip, firewall_port);
  else {
    char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username);

    snprintf (contact, 1000, "<%s:%s@%s:%s>", scheme, tmp2, locip, firewall_port);
    osip_free (tmp2);
  }
  if (firewall_ip[0] != '\0') {
#ifdef USE_LOCALIP_WITH_LOCALPROXY      /* disable this code for local testing because it adds an extra DNS */
    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 (excontext, &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, "<%s:%s:%s>", scheme, firewall_ip, firewall_port);
        else {
          char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username);

          snprintf (contact, 1000, "<%s:%s@%s:%s>", scheme, tmp2, firewall_ip, firewall_port);
          osip_free (tmp2);
        }
      }
    }
#else
    if (request->to->url->username == NULL)
      snprintf (contact, 1000, "<%s:%s:%s>", scheme, firewall_ip, firewall_port);
    else {
      char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username);

      snprintf (contact, 1000, "<%s:%s@%s:%s>", scheme, tmp2, firewall_ip, firewall_port);
      osip_free (tmp2);
    }
#endif
  }

  {
    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) + strlen (";transport=>") < 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);

  if (excontext->eXtl_transport.tl_update_local_target!=NULL)
    excontext->eXtl_transport.tl_update_local_target(excontext, response);
  return OSIP_SUCCESS;
}