Ejemplo n.º 1
0
/*
 * Do loose routing as defined in RFC3621
 */
int loose_route(struct sip_msg* _m, char* _s1, char* _s2)
{
	struct hdr_field* hdr;
	struct sip_uri puri;
	rr_t* rt;
	int ret;
	str* uri;

	if (find_first_route(_m) != 0) {
		DBG("loose_route: There is no Route HF\n");
		return -1;
	}

	if (parse_sip_msg_uri(_m) == -1) {
		LOG(L_ERR, "loose_route: Error while parsing Request URI\n");
		return -1;
	}

	hdr = _m->route;
	rt = (rr_t*)hdr->parsed;
	uri = &rt->nameaddr.uri;

	if (parse_uri(uri->s, uri->len, &puri) < 0) {
		LOG(L_ERR, "loose_route: Error while parsing the first route URI\n");
		return -1;
	}

	if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no)||
			_m->parsed_uri.type == TEL_URI_T ||
			_m->parsed_uri.type == TELS_URI_T) {
		DBG("loose_route: RURI is myself (or tel URI)\n");
		if ((ret = is_myself(&puri.host, puri.port_no)) == 1 &&
			!(enable_double_rr && is_2rr(&puri.params))) {
			DBG("loose_route: found preloaded loose route\n");
			return after_loose(_m, &puri, ret, 1);
		} else {
			if (has_to_tag(_m) == 1) {
				return after_strict(_m, &puri, ret);
			} else {
				LOG(L_WARN, "loose_route: pre-loaded strict routing?!\n");
				return -1;
			}
		}
	} else {
		DBG("loose_route: RURI is NOT myself\n");
		if (is_myself(&puri.host, puri.port_no)) {
			return after_loose(_m, &puri, 1, 0);
		} else {
			store_next_route_in_avps(uri);
			//LOG(L_WARN, "loose_route: no routing target is local\n");
			//return -1;
			return after_loose(_m, &puri, 0, 0);
		}
	}
}
Ejemplo n.º 2
0
/*!
 * \brief Do loose routing as per RFC3261
 * \param _m SIP message
 * \return -1 on failure, 1 on success
 */
int loose_route(struct sip_msg* _m)
{
    int ret;

    if (find_first_route(_m) != 0) {
        LM_DBG("There is no Route HF\n");
        return -1;
    }

    if (parse_sip_msg_uri(_m)<0) {
        LM_ERR("failed to parse Request URI\n");
        return -1;
    }

    ret = is_preloaded(_m);
    if (ret < 0) {
        return -1;
    } else if (ret == 1) {
        return after_loose(_m, 1);
    } else {
        if (is_myself(&_m->parsed_uri)) {
            return after_strict(_m);
        } else {
            return after_loose(_m, 0);
        }
    }
}
Ejemplo n.º 3
0
void sd_notify_handler(struct sd_node *sender, void *msg, size_t msg_len)
{
	struct event_struct *cevent;
	struct work_notify *w;

	dprintf("size: %zd, from: %s\n", msg_len, node_to_str(sender));

	w = zalloc(sizeof(*w));
	if (!w)
		return;

	cevent = &w->cev;
	cevent->ctype = EVENT_NOTIFY;

	vprintf(SDOG_DEBUG, "allow new deliver %p\n", cevent);

	w->sender = *sender;
	if (msg_len) {
		w->msg = zalloc(msg_len);
		if (!w->msg)
			return;
		memcpy(w->msg, msg, msg_len);
	} else
		w->msg = NULL;

	if (is_myself(sender->addr, sender->port)) {
		w->req = list_first_entry(&sys->pending_list, struct request,
					  pending_list);
		list_del(&w->req->pending_list);
	}
Ejemplo n.º 4
0
static int
matches_me(struct Output *out, unsigned ip, unsigned port)
{
    unsigned i;

    for (i=0; i<8; i++) {
        if (is_myself(&out->src[i], ip, port))
            return 1;
    }
    return 0;
}
Ejemplo n.º 5
0
/*
 * Pass on a notification message from the cluster driver.
 *
 * Must run in the main thread as it accesses unlocked state like
 * sys->pending_list.
 */
void sd_notify_handler(struct sd_node *sender, void *data, size_t data_len)
{
	struct vdi_op_message *msg = data;
	struct sd_op_template *op = get_sd_op(msg->req.opcode);
	int ret = msg->rsp.result;
	struct request *req = NULL;

	dprintf("op %s, size: %zd, from: %s\n",
		op_name(op), data_len, node_to_str(sender));

	if (is_myself(sender->nid.addr, sender->nid.port)) {
		req = list_first_entry(&sys->pending_list, struct request,
				       pending_list);
		list_del(&req->pending_list);
	}
Ejemplo n.º 6
0
static int get_vdi_bitmap_from(struct sd_node *node)
{
	struct sd_req hdr;
	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
	static DECLARE_BITMAP(tmp_vdi_inuse, SD_NR_VDIS);
	int fd, i, ret = SD_RES_SUCCESS;
	unsigned int rlen, wlen;
	char host[128];

	if (is_myself(node->addr, node->port))
		goto out;

	addr_to_str(host, sizeof(host), node->addr, 0);

	fd = connect_to(host, node->port);
	if (fd < 0) {
		vprintf(SDOG_ERR, "unable to get the VDI bitmap from %s: %m\n", host);
		ret = -SD_RES_EIO;
		goto out;
	}

	vprintf(SDOG_ERR, "%s:%d\n", host, node->port);

	memset(&hdr, 0, sizeof(hdr));
	hdr.opcode = SD_OP_READ_VDIS;
	hdr.epoch = sys->epoch;
	hdr.data_length = sizeof(tmp_vdi_inuse);
	rlen = hdr.data_length;
	wlen = 0;

	ret = exec_req(fd, &hdr, (char *)tmp_vdi_inuse,
			&wlen, &rlen);

	close(fd);

	if (ret || rsp->result != SD_RES_SUCCESS) {
		vprintf(SDOG_ERR, "unable to get the VDI bitmap (%d, %d)\n", ret,
				rsp->result);
		goto out;
	}

	for (i = 0; i < ARRAY_SIZE(sys->vdi_inuse); i++)
		sys->vdi_inuse[i] |= tmp_vdi_inuse[i];
out:
	return ret;
}
Ejemplo n.º 7
0
/*!
 * \brief Previous hop was a loose router, handle this case
 * \param _m SIP message
 * \param preloaded do we have a preloaded route set
 * \return -1 on failure, 1 on success
 */
static inline int after_loose(struct sip_msg* _m, int preloaded)
{
    struct hdr_field* hdr;
    struct sip_uri puri;
    rr_t* rt;
    int res;
    int status = RR_DRIVEN;
    str uri;
    struct socket_info *si;
    int uri_is_myself, next_is_strict;
    int use_ob = 0;

    hdr = _m->route;
    rt = (rr_t*)hdr->parsed;
    uri = rt->nameaddr.uri;

    /* reset rr handling static vars for safety in error case */
    routed_msg_id = 0;

    if (parse_uri(uri.s, uri.len, &puri) < 0) {
        LM_ERR("failed to parse the first route URI\n");
        return RR_ERROR;
    }

    next_is_strict = is_strict(&puri.params);
    routed_params = puri.params;
    uri_is_myself = is_myself(&puri);

    /* IF the URI was added by me, remove it */
    if (uri_is_myself>0)
    {
        LM_DBG("Topmost route URI: '%.*s' is me\n",
               uri.len, ZSW(uri.s));
        /* set the hooks for the params */
        routed_msg_id = _m->id;

        if ((use_ob = process_outbound(_m, puri.user)) < 0) {
            LM_INFO("failed to process outbound flow-token\n");
            return FLOW_TOKEN_BROKEN;
        }

        if (!rt->next) {
            /* No next route in the same header, remove the whole header
             * field immediately
             */
            if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
                LM_ERR("failed to remove Route HF\n");
                return RR_ERROR;
            }

            res = find_next_route(_m, &hdr);
            if (res < 0) {
                LM_ERR("failed to find next route\n");
                return RR_ERROR;
            }
            if (res > 0) { /* No next route found */
                LM_DBG("No next URI found\n");
                status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);
                goto done;
            }
            rt = (rr_t*)hdr->parsed;
        } else rt = rt->next;

        if (enable_double_rr && is_2rr(&puri.params)) {
            /* double route may occure due different IP and port, so force as
             * send interface the one advertise in second Route */
            if (parse_uri(rt->nameaddr.uri.s,rt->nameaddr.uri.len,&puri)<0) {
                LM_ERR("failed to parse the double route URI\n");
                return RR_ERROR;
            }

            if (!use_ob) {
                si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
                if (si) {
                    set_force_socket(_m, si);
                } else {
                    if (enable_socket_mismatch_warning)
                        LM_WARN("no socket found for match second RR\n");
                }
            }

            if (!rt->next) {
                /* No next route in the same header, remove the whole header
                 * field immediately */
                if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
                    LM_ERR("failed to remove Route HF\n");
                    return RR_ERROR;
                }
                res = find_next_route(_m, &hdr);
                if (res < 0) {
                    LM_ERR("failed to find next route\n");
                    return RR_ERROR;
                }
                if (res > 0) { /* No next route found */
                    LM_DBG("no next URI found\n");
                    status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);
                    goto done;
                }
                rt = (rr_t*)hdr->parsed;
            } else rt = rt->next;
        }

        uri = rt->nameaddr.uri;
        if (parse_uri(uri.s, uri.len, &puri) < 0) {
            LM_ERR("failed to parse the first route URI\n");
            return RR_ERROR;
        }
    } else {
#ifdef ENABLE_USER_CHECK
        /* check if it the ignored user */
        if(uri_is_myself < 0)
            return NOT_RR_DRIVEN;
#endif
        LM_DBG("Topmost URI is NOT myself\n");
        routed_params.s = NULL;
        routed_params.len = 0;
    }

    LM_DBG("URI to be processed: '%.*s'\n", uri.len, ZSW(uri.s));
    if (next_is_strict) {
        LM_DBG("Next URI is a strict router\n");
        if (handle_sr(_m, hdr, rt) < 0) {
            LM_ERR("failed to handle strict router\n");
            return RR_ERROR;
        }
    } else {
        /* Next hop is loose router */
        LM_DBG("Next URI is a loose router\n");

        if (!use_ob) {
            if(get_maddr_uri(&uri, &puri)!=0) {
                LM_ERR("checking maddr failed\n");
                return RR_ERROR;
            }

            if (set_dst_uri(_m, &uri) < 0) {
                LM_ERR("failed to set dst_uri\n");
                return RR_ERROR;
            }
            /* dst_uri changed, so it makes sense to re-use the current uri for
            forking */
            ruri_mark_new(); /* re-use uri for serial forking */
        }

        /* There is a previous route uri which was 2nd uri of mine
         * and must be removed here */
        if (rt != hdr->parsed) {
            if (!del_lump(_m, hdr->body.s - _m->buf,
                          rt->nameaddr.name.s - hdr->body.s, 0)) {
                LM_ERR("failed to remove Route HF\n");
                return RR_ERROR;
            }
        }
    }

done:
    if (use_ob == 1)
        status = RR_OB_DRIVEN;

    /* run RR callbacks only if we have Route URI parameters */
    if(routed_params.len > 0)
        run_rr_callbacks( _m, &routed_params );
    return status;
}
Ejemplo n.º 8
0
/*!
 * \brief Previous hop was a strict router, handle this case
 * \param _m SIP message
 * \return -1 on error, 1 on success
 */
static inline int after_strict(struct sip_msg* _m)
{
    int res, rem_len;
    struct hdr_field* hdr;
    struct sip_uri puri;
    rr_t* rt, *prev;
    char* rem_off;
    str uri;
    struct socket_info *si;

    hdr = _m->route;
    rt = (rr_t*)hdr->parsed;
    uri = rt->nameaddr.uri;

    /* reset rr handling static vars for safety in error case */
    routed_msg_id = 0;
    routed_params.s = NULL;
    routed_params.len = 0;

    if (parse_uri(uri.s, uri.len, &puri) < 0) {
        LM_ERR("failed to parse the first route URI\n");
        return RR_ERROR;
    }

    if ( enable_double_rr && is_2rr(&puri.params) && is_myself(&puri)) {
        /* double route may occure due different IP and port, so force as
         * send interface the one advertise in second Route */
        si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
        if (si) {
            set_force_socket(_m, si);
        } else {
            if (enable_socket_mismatch_warning)
                LM_WARN("no socket found for match second RR\n");
        }

        if (!rt->next) {
            /* No next route in the same header, remove the whole header
             * field immediately
             */
            if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
                LM_ERR("failed to remove Route HF\n");
                return RR_ERROR;
            }
            res = find_next_route(_m, &hdr);
            if (res < 0) {
                LM_ERR("searching next route failed\n");
                return RR_ERROR;
            }
            if (res > 0) { /* No next route found */
                LM_DBG("after_strict: No next URI found\n");
                return NOT_RR_DRIVEN;
            }
            rt = (rr_t*)hdr->parsed;
        } else rt = rt->next;

        /* parse the new found uri */
        uri = rt->nameaddr.uri;
        if (parse_uri(uri.s, uri.len, &puri) < 0) {
            LM_ERR("failed to parse URI\n");
            return RR_ERROR;
        }
    }

    /* set the hooks for the param
     * important note: RURI is already parsed by the above function, so
     * we just used it without any checking */
    routed_msg_id = _m->id;
    routed_params = _m->parsed_uri.params;

    if (is_strict(&puri.params)) {
        LM_DBG("Next hop: '%.*s' is strict router\n", uri.len, ZSW(uri.s));
        /* Previous hop was a strict router and the next hop is strict
         * router too. There is no need to save R-URI again because it
         * is saved already. In fact, in this case we will behave exactly
         * like a strict router. */

        /* Note: when there is only one Route URI left (endpoint), it will
         * always be a strict router because endpoints don't use ;lr parameter
         * In this case we will simply put the URI in R-URI and forward it,
         * which will work perfectly */
        if(get_maddr_uri(&uri, &puri)!=0) {
            LM_ERR("failed to check maddr\n");
            return RR_ERROR;
        }
        if (rewrite_uri(_m, &uri) < 0) {
            LM_ERR("failed to rewrite request URI\n");
            return RR_ERROR;
        }

        if (rt->next) {
            rem_off = hdr->body.s;
            rem_len = rt->next->nameaddr.name.s - hdr->body.s;
        } else {
            rem_off = hdr->name.s;
            rem_len = hdr->len;
        }
        if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
            LM_ERR("failed to remove Route HF\n");
            return RR_ERROR;
        }
    } else {
        LM_DBG("Next hop: '%.*s' is loose router\n",
               uri.len, ZSW(uri.s));

        if(get_maddr_uri(&uri, &puri)!=0) {
            LM_ERR("failed to check maddr\n");
            return RR_ERROR;
        }
        if (set_dst_uri(_m, &uri) < 0) {
            LM_ERR("failed to set dst_uri\n");
            return RR_ERROR;
        }

        /* Next hop is a loose router - Which means that is is not endpoint yet
         * In This case we have to recover from previous strict routing, that
         * means we have to find the last Route URI and put in in R-URI and
         * remove the last Route URI. */
        if (rt != hdr->parsed) {
            /* There is a previous route uri which was 2nd uri of mine
             * and must be removed here */
            rem_off = hdr->body.s;
            rem_len = rt->nameaddr.name.s - hdr->body.s;
            if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
                LM_ERR("failed to remove Route HF\n");
                return RR_ERROR;
            }
        }


        res = find_rem_target(_m, &hdr, &rt, &prev);
        if (res < 0) {
            LM_ERR("searching for last Route URI failed\n");
            return RR_ERROR;
        } else if (res > 0) {
            /* No remote target is an error */
            return RR_ERROR;
        }

        uri = rt->nameaddr.uri;
        if(get_maddr_uri(&uri, 0)!=0) {
            LM_ERR("checking maddr failed\n");
            return RR_ERROR;
        }
        if (rewrite_uri(_m, &uri) < 0) {
            LM_ERR("failed to rewrite R-URI\n");
            return RR_ERROR;
        }

        /* The first character if uri will be either '<' when it is the
         * only URI in a Route header field or ',' if there is more than
         * one URI in the header field */
        LM_DBG("The last route URI: '%.*s'\n", rt->nameaddr.uri.len,
               ZSW(rt->nameaddr.uri.s));

        if (prev) {
            rem_off = prev->nameaddr.name.s + prev->len;
            rem_len = rt->nameaddr.name.s + rt->len - rem_off;
        } else {
            rem_off = hdr->name.s;
            rem_len = hdr->len;
        }
        if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
            LM_ERR("failed to remove Route HF\n");
            return RR_ERROR;
        }
    }

    /* run RR callbacks only if we have Route URI parameters */
    if(routed_params.len > 0)
        run_rr_callbacks( _m, &routed_params );

    return RR_DRIVEN;
}
Ejemplo n.º 9
0
/*
 * Do loose routing as defined in RFC3261
 */
int loose_route(struct sip_msg* _m)
{
	int ret;

	ctx_routing_set(0);

	if (find_first_route(_m) != 0) {
		LM_DBG("There is no Route HF\n");
		return -1;
	}

	if (parse_sip_msg_uri(_m)<0) {
		LM_ERR("failed to parse Request URI\n");
		return -1;
	}

	ret = is_preloaded(_m);
	if (ret < 0) {
		return -1;
	} else if (ret == 1) {
		return after_loose(_m, 1);
	} else {
#ifdef ENABLE_USER_CHECK
		if (is_myself(&_m->parsed_uri.user, &_m->parsed_uri.host,
		_m->parsed_uri.port_no) && !(_m->parsed_uri.gr.s && _m->parsed_uri.gr.len)) {
#else
		if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no) && !(_m->parsed_uri.gr.s && _m->parsed_uri.gr.len)) {
#endif
			return after_strict(_m);
		} else {
			return after_loose(_m, 0);
		}
	}
}


int get_route_params(struct sip_msg *msg, str *val)
{
	if(msg==NULL)
		return -1;

	/* check if params are present */
	if ( (val=ctx_rrparam_get())==NULL )
		return -1;

	return 0;
}


int check_route_param(struct sip_msg * msg, regex_t* re)
{
	regmatch_t pmatch;
	char bk;
	str params;
	str *rparams;

	/* check if params are present */
	if ( (rparams=ctx_rrparam_get())==NULL || rparams->len==0)
		return -1;

	/* include also the first ';' */
	for( params=*rparams ; params.s[0]!=';' ; params.s--,params.len++ );

	/* do the well-known trick to convert to null terminted */
	bk = params.s[params.len];
	params.s[params.len] = 0;
	LM_DBG("params are <%s>\n", params.s);
	if (regexec( re, params.s, 1, &pmatch, 0)!=0) {
		params.s[params.len] = bk;
		return -1;
	} else {
		params.s[params.len] = bk;
		return 0;
	}
}
Ejemplo n.º 10
0
static inline int after_loose(struct sip_msg* _m, int preloaded)
{
	struct hdr_field* hdr;
	struct sip_uri puri;
	struct sip_uri puri2;
	rr_t* rt;
	int res;
	int status;
#ifdef ENABLE_USER_CHECK
	int ret;
#endif
	str uri;
	struct socket_info *si;
	int force_ss = 0;

	hdr = _m->route;
	rt = (rr_t*)hdr->parsed;
	uri = rt->nameaddr.uri;

	if (parse_uri(uri.s, uri.len, &puri) < 0) {
		LM_ERR("failed to parse the first route URI\n");
		return RR_ERROR;
	}

	/* IF the URI was added by me, remove it */
#ifdef ENABLE_USER_CHECK
	ret=is_myself(&puri.user, &puri.host, puri.port_no);
	if (ret>0)
#else
	if (is_myself(&puri.host, puri.port_no))
#endif
	{
		LM_DBG("Topmost route URI: '%.*s' is me\n",
			uri.len, ZSW(uri.s));
		/* set the hooks for the params -bogdan */
		ctx_rrparam_set( &puri.params );

		/* if last route in header, gonna get del_lumped now,
		 * if not, it will be taken care of later
		 * Mark it now as deleted */
		rt->deleted = 1;

		if (!rt->next) {
			/* No next route in the same header, remove the whole header
			 * field immediately
			 */
			if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
				LM_ERR("failed to remove Route HF\n");
				return RR_ERROR;
			}

			rt->deleted = 1;

			res = find_next_route(_m, &hdr);
			if (res < 0) {
				LM_ERR("failed to find next route\n");
				return RR_ERROR;
			}
			if (res > 0) { /* No next route found */
				LM_DBG("No next URI found!\n");
				status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);

				/*same case as LL , if there is no next route*/
				ctx_routing_set( ROUTING_LL );
				force_ss = 1;

				goto done;
			}
			rt = (rr_t*)hdr->parsed;
		} else rt = rt->next;

		if (enable_double_rr && is_2rr(&puri.params)) {
			force_ss = 0;
			/* double route may occure due different IP and port, so force as
			 * send interface the one advertise in second Route */
			if (parse_uri(rt->nameaddr.uri.s,rt->nameaddr.uri.len,&puri)<0) {
				LM_ERR("failed to parse the double route URI\n");
				return RR_ERROR;
			}
			set_sip_defaults( puri.port_no, puri.proto);
			si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
			if (si) {
				_m->force_send_socket = si;
			} else {
				if (enable_socket_mismatch_warning)
					LM_WARN("no socket found to match 2nd RR [%d][%.*s:%d]\n",
						puri.proto, puri.host.len, puri.host.s, puri.port_no);
			}

			rt->deleted = 1;

			if (!rt->next) {
				/* No next route in the same header, remove the whole header
				 * field immediately */
				if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
					LM_ERR("failed to remove Route HF\n");
					return RR_ERROR;
				}

				res = find_next_route(_m, &hdr);
				if (res < 0) {
					LM_ERR("failed to find next route\n");
					return RR_ERROR;
				}
				if (res > 0) { /* No next route found */
					LM_DBG("no next URI found\n");
					status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);

					/* same case as LL , if there is no next route */
					ctx_routing_set( ROUTING_LL );

					goto done;
				}
				rt = (rr_t*)hdr->parsed;
			} else rt = rt->next;
		} else {
			force_ss = 1;
		}

		uri = rt->nameaddr.uri;
		if (parse_uri(uri.s, uri.len, &puri2) < 0) {
			LM_ERR("failed to parse the first route URI\n");
			return RR_ERROR;
		}
	} else {
#ifdef ENABLE_USER_CHECK
		/* check if it the ignored user */
		if(ret < 0)
			return NOT_RR_DRIVEN;
#endif
		LM_DBG("Topmost URI is NOT myself\n");
		memcpy(&puri2, &puri, sizeof(struct sip_uri));
	}

	LM_DBG("URI to be processed: '%.*s'\n", uri.len, ZSW(uri.s));
	if (is_strict(&puri2.params)) {
		LM_DBG("Next URI is a strict router\n");

		ctx_routing_set( ROUTING_LS );
		if (handle_sr(_m, hdr, rt) < 0) {
			LM_ERR("failed to handle strict router\n");
			return RR_ERROR;
		}
	} else {
		/* Next hop is loose router */
		LM_DBG("Next URI is a loose router\n");

		ctx_routing_set( ROUTING_LL );

		if(get_maddr_uri(&uri, &puri2)!=0) {
			LM_ERR("checking maddr failed\n");
			return RR_ERROR;
		}
		if (set_dst_uri(_m, &uri) < 0) {
			LM_ERR("failed to set dst_uri\n");
			return RR_ERROR;
		}

		/* There is a previous route uri which was 2nd uri of mine
		 * and must be removed here */
		if (rt != hdr->parsed) {
			if (!del_lump(_m, hdr->body.s - _m->buf,
			rt->nameaddr.name.s - hdr->body.s, 0)) {
				LM_ERR("failed to remove Route HF\n");
				return RR_ERROR;
			}

			((rr_t *)hdr->parsed)->deleted = 1;
		}
	}
	status = RR_DRIVEN;

done:
	if (force_ss && !preloaded)
		_m->force_send_socket = _m->rcv.bind_address;
	/* run RR callbacks -bogdan */
	run_rr_callbacks( _m, &puri.params );
	return status;
}
Ejemplo n.º 11
0
/*
 * Do loose routing as defined in RFC3261
 */
int loose_route(struct sip_msg* _m, char* _s1, char* _s2)
{
	int ret;

	removed_routes = 0;
	routing_type = 0;

	if (find_first_route(_m) != 0) {
		LM_DBG("There is no Route HF\n");
		return -1;
	}
		
	if (parse_sip_msg_uri(_m)<0) {
		LM_ERR("failed to parse Request URI\n");
		return -1;
	}

	ret = is_preloaded(_m);
	if (ret < 0) {
		return -1;
	} else if (ret == 1) {
		return after_loose(_m, 1);
	} else {
#ifdef ENABLE_USER_CHECK
		if (is_myself(&_m->parsed_uri.user, &_m->parsed_uri.host,
		_m->parsed_uri.port_no)) {
#else
		if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no)) {
#endif
			return after_strict(_m);
		} else {
			return after_loose(_m, 0);
		}
	}
}


int get_route_params(struct sip_msg *msg, str *val)
{
	if(msg==NULL)
		return -1;

	/* check if the hooked params belong to the same message */
	if (routed_msg_id != msg->id)
		return -1;

	val->s = routed_params.s;
	val->len = routed_params.len;

	return 0;
}


int check_route_param(struct sip_msg * msg, regex_t* re)
{
	regmatch_t pmatch;
	char bk;
	str params;

	/* check if the hooked params belong to the same message */
	if (routed_msg_id != msg->id)
		return -1;

	/* check if params are present */
	if ( !routed_params.s || !routed_params.len )
		return -1;

	/* include also the first ';' */
	for( params=routed_params ; params.s[0]!=';' ; params.s--,params.len++ );

	/* do the well-known trick to convert to null terminted */
	bk = params.s[params.len];
	params.s[params.len] = 0;
	LM_DBG("params are <%s>\n", params.s);
	if (regexec( re, params.s, 1, &pmatch, 0)!=0) {
		params.s[params.len] = bk;
		return -1;
	} else {
		params.s[params.len] = bk;
		return 0;
	}
}