Example #1
0
/* Calculate new target for the request */
static pj_status_t proxy_calculate_target(pjsip_rx_data *rdata,
        pjsip_tx_data *tdata)
{
    pjsip_sip_uri *target;

    /* RFC 3261 Section 16.5 Determining Request Targets */

    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;

    /* If the Request-URI of the request contains an maddr parameter, the
     * Request-URI MUST be placed into the target set as the only target
     * URI, and the proxy MUST proceed to Section 16.6.
     */
    if (target->maddr_param.slen) {
        proxy_postprocess(tdata);
        return PJ_SUCCESS;
    }


    /* If the domain of the Request-URI indicates a domain this element is
     * not responsible for, the Request-URI MUST be placed into the target
     * set as the only target, and the element MUST proceed to the task of
     * Request Forwarding (Section 16.6).
     */
    if (!is_uri_local(target)) {
        proxy_postprocess(tdata);
        return PJ_SUCCESS;
    }

    /* If the target set for the request has not been predetermined as
     * described above, this implies that the element is responsible for the
     * domain in the Request-URI, and the element MAY use whatever mechanism
     * it desires to determine where to send the request.
     */

    /* We're not interested to receive request destined to us, so
     * respond with 404/Not Found (only if request is not ACK!).
     */
    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
        pjsip_endpt_respond_stateless(global.endpt, rdata,
                                      PJSIP_SC_NOT_FOUND, NULL,
                                      NULL, NULL);
    }

    /* Delete the request since we're not forwarding it */
    pjsip_tx_data_dec_ref(tdata);

    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_FOUND);
}
Example #2
0
// Return true if there are no route headers, or there is exactly one,
// which is local
bool PJUtils::check_route_headers(pjsip_rx_data* rdata)
{
  // Get all the route headers
  int count = 0;
  bool local = true;
  pjsip_route_hdr* route_hdr = (pjsip_route_hdr*)pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ROUTE, NULL);

  while (route_hdr != NULL)
  {
    count++;
    local = (is_uri_local(route_hdr->name_addr.uri)) || (is_home_domain(route_hdr->name_addr.uri));
    route_hdr = (pjsip_route_hdr*)pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ROUTE, route_hdr->next);
  }

  return (count < 2 && local);
}
Example #3
0
/// Checks whether the next Route header in the message refers to this node,
/// and optionally returns the header.  If there are no Route headers it
/// returns false.
pj_bool_t PJUtils::is_next_route_local(const pjsip_msg* msg, pjsip_route_hdr* start, pjsip_route_hdr** hdr)
{
  bool rc = false;
  pjsip_route_hdr* route_hdr = (pjsip_route_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_ROUTE, (start != NULL) ? start->next : NULL);

  if (route_hdr != NULL)
  {
    // Found the next Route header, so check whether the URI corresponds to
    // this node or one of its aliases.
    pjsip_uri* uri = route_hdr->name_addr.uri;
    LOG_DEBUG("Found Route header, URI = %s", uri_to_string(PJSIP_URI_IN_ROUTING_HDR, uri).c_str());
    if ((is_home_domain(uri)) || (is_uri_local(uri)))
    {
      rc = true;
      if (hdr != NULL)
      {
        *hdr = route_hdr;
      }
    }
  }
  return rc;
}
Example #4
0
/* Process route information in the reqeust */
static pj_status_t proxy_process_routing(pjsip_tx_data *tdata)
{
    pjsip_sip_uri *target;
    pjsip_route_hdr *hroute;

    /* RFC 3261 Section 16.4 Route Information Preprocessing */

    target = (pjsip_sip_uri*) tdata->msg->line.req.uri;

    /* The proxy MUST inspect the Request-URI of the request.  If the
     * Request-URI of the request contains a value this proxy previously
     * placed into a Record-Route header field (see Section 16.6 item 4),
     * the proxy MUST replace the Request-URI in the request with the last
     * value from the Route header field, and remove that value from the
     * Route header field.  The proxy MUST then proceed as if it received
     * this modified request.
     */
    if (is_uri_local(target)) {
        pjsip_route_hdr *r;
        pjsip_sip_uri *uri;

        /* Find the first Route header */
        r = hroute = (pjsip_route_hdr*)
                     pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
        if (r == NULL) {
            /* No Route header. This request is destined for this proxy. */
            return PJ_SUCCESS;
        }

        /* Find the last Route header */
        while ( (r=(pjsip_route_hdr*)pjsip_msg_find_hdr(tdata->msg,
                   PJSIP_H_ROUTE,
                   r->next)) != NULL )
        {
            hroute = r;
        }

        /* If the last Route header doesn't have ";lr" parameter, then
         * this is a strict-routed request indeed, and we follow the steps
         * in processing strict-route requests above.
         *
         * But if it does contain ";lr" parameter, skip the strict-route
         * processing.
         */
        uri = (pjsip_sip_uri*)
              pjsip_uri_get_uri(&hroute->name_addr);
        if (uri->lr_param == 0) {
            /* Yes this is strict route, so:
             * - replace req URI with the URI in Route header,
             * - remove the Route header,
             * - proceed as if it received this modified request.
            */
            tdata->msg->line.req.uri = hroute->name_addr.uri;
            target = (pjsip_sip_uri*) tdata->msg->line.req.uri;
            pj_list_erase(hroute);
        }
    }

    /* If the Request-URI contains a maddr parameter, the proxy MUST check
     * to see if its value is in the set of addresses or domains the proxy
     * is configured to be responsible for.  If the Request-URI has a maddr
     * parameter with a value the proxy is responsible for, and the request
     * was received using the port and transport indicated (explicitly or by
     * default) in the Request-URI, the proxy MUST strip the maddr and any
     * non-default port or transport parameter and continue processing as if
     * those values had not been present in the request.
     */
    if (target->maddr_param.slen != 0) {
        pjsip_sip_uri maddr_uri;

        maddr_uri.host = target->maddr_param;
        maddr_uri.port = global.port;

        if (is_uri_local(&maddr_uri)) {
            target->maddr_param.slen = 0;
            target->port = 0;
            target->transport_param.slen = 0;
        }
    }

    /* If the first value in the Route header field indicates this proxy,
     * the proxy MUST remove that value from the request.
     */
    hroute = (pjsip_route_hdr*)
             pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
    if (hroute && is_uri_local((pjsip_sip_uri*)hroute->name_addr.uri)) {
        pj_list_erase(hroute);
    }

    return PJ_SUCCESS;
}