123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- /**
- * $Id$
- *
- * Copyright (C) 2011 Daniel-Constantin Mierla (asipto.com)
- *
- * This file is part of Kamailio, a free SIP server.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include "../../dprint.h"
- #include "../../dset.h"
- #include "../../forward.h"
- #include "../../parser/parse_uri.h"
- #include "../../resolve.h"
- #include "corex_lib.h"
- /**
- * append new branches with generic parameters
- */
- int corex_append_branch(sip_msg_t *msg, gparam_t *pu, gparam_t *pq)
- {
- str uri = {0};
- str qv = {0};
- int ret = 0;
- qvalue_t q = Q_UNSPECIFIED;
- flag_t branch_flags = 0;
- if (pu!=NULL)
- {
- if(fixup_get_svalue(msg, pu, &uri)!=0)
- {
- LM_ERR("cannot get the URI parameter\n");
- return -1;
- }
- }
- if (pq!=NULL)
- {
- if(fixup_get_svalue(msg, pq, &qv)!=0)
- {
- LM_ERR("cannot get the Q parameter\n");
- return -1;
- }
- if(qv.len>0 && str2q(&q, qv.s, qv.len)<0)
- {
- LM_ERR("cannot parse the Q parameter\n");
- return -1;
- }
- }
- getbflagsval(0, &branch_flags);
- ret = append_branch(msg, (uri.len>0)?&uri:0, &msg->dst_uri,
- &msg->path_vec, q, branch_flags,
- msg->force_send_socket, 0, 0, 0, 0);
- if(uri.len<=0)
- {
- /* reset all branch attributes if r-uri was shifted to branch */
- reset_force_socket(msg);
- setbflagsval(0, 0);
- if(msg->dst_uri.s!=0)
- pkg_free(msg->dst_uri.s);
- msg->dst_uri.s = 0;
- msg->dst_uri.len = 0;
- /* if this is a cloned message, don't free the path vector as it was copied into shm memory and will be freed as contiguous block*/
- if (!(msg->msg_flags&FL_SHM_CLONE)) {
- if(msg->path_vec.s!=0)
- pkg_free(msg->path_vec.s);
- msg->path_vec.s = 0;
- msg->path_vec.len = 0;
- }
- }
- return ret;
- }
- typedef struct corex_alias {
- str alias;
- unsigned short port;
- unsigned short proto;
- int flags;
- struct corex_alias* next;
- } corex_alias_t;
- static corex_alias_t *_corex_alias_list = NULL;
- int corex_add_alias_subdomains(char* aliasval)
- {
- char *p = NULL;
- corex_alias_t ta;
- corex_alias_t *na;
- memset(&ta, 0, sizeof(corex_alias_t));
- p = strchr(aliasval, ':');
- if(p==NULL) {
- /* only hostname */
- ta.alias.s = aliasval;
- ta.alias.len = strlen(aliasval);
- goto done;
- }
- if((p-aliasval)==3 || (p-aliasval)==4) {
- /* check if it is protocol */
- if((p-aliasval)==3 && strncasecmp(aliasval, "udp", 3)==0) {
- ta.proto = PROTO_UDP;
- } else if((p-aliasval)==3 && strncasecmp(aliasval, "tcp", 3)==0) {
- ta.proto = PROTO_TCP;
- } else if((p-aliasval)==3 && strncasecmp(aliasval, "tls", 3)==0) {
- ta.proto = PROTO_TLS;
- } else if((p-aliasval)==4 && strncasecmp(aliasval, "sctp", 4)==0) {
- ta.proto = PROTO_SCTP;
- } else {
- /* use hostname */
- ta.alias.s = aliasval;
- ta.alias.len = p - aliasval;
- }
- }
- if(ta.alias.len==0) {
- p++;
- if(p>=aliasval+strlen(aliasval))
- goto error;
- ta.alias.s = p;
- p = strchr(ta.alias.s, ':');
- if(p==NULL) {
- ta.alias.len = strlen(ta.alias.s);
- goto done;
- }
- }
- /* port */
- p++;
- if(p>=aliasval+strlen(aliasval))
- goto error;
- ta.port = str2s(p, strlen(p), NULL);
- done:
- if(ta.alias.len==0)
- goto error;
- na = (corex_alias_t*)pkg_malloc(sizeof(corex_alias_t));
- if(na==NULL) {
- LM_ERR("no memory for adding alias subdomains: %s\n", aliasval);
- return -1;
- }
- memcpy(na, &ta, sizeof(corex_alias_t));
- na->next = _corex_alias_list;
- _corex_alias_list = na;
- return 0;
- error:
- LM_ERR("error adding alias subdomains: %s\n", aliasval);
- return -1;
- }
- int corex_check_self(str* host, unsigned short port, unsigned short proto)
- {
- corex_alias_t *ta;
- for(ta=_corex_alias_list; ta; ta=ta->next) {
- if(host->len<ta->alias.len)
- continue;
- if(ta->port!=0 && port!=0 && ta->port!=port)
- continue;
- if(ta->proto!=0 && proto!=0 && ta->proto!=proto)
- continue;
- if(host->len==ta->alias.len
- && strncasecmp(host->s, ta->alias.s, host->len)==0) {
- /* match domain */
- LM_DBG("check self domain match: %d:%.*s:%d\n", (int)ta->port,
- ta->alias.len, ta->alias.s, (int)ta->proto);
- return 1;
- }
- if(strncasecmp(ta->alias.s, host->s + host->len - ta->alias.len,
- ta->alias.len)==0) {
- if(host->s[host->len - ta->alias.len - 1]=='.') {
- /* match sub-domain */
- LM_DBG("check self sub-domain match: %d:%.*s:%d\n", (int)ta->port,
- ta->alias.len, ta->alias.s, (int)ta->proto);
- return 1;
- }
- }
- }
- return 0; /* no match */
- }
- int corex_register_check_self(void)
- {
- if(_corex_alias_list==NULL)
- return 0;
- if (register_check_self_func(corex_check_self) <0 ) {
- LM_ERR("failed to register check self function\n");
- return -1;
- }
- return 0;
- }
- int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto)
- {
- str dest = {0};
- int ret = 0;
- struct sip_uri next_hop, *u;
- struct dest_info dst;
- char *p;
- if (pu)
- {
- if (fixup_get_svalue(msg, pu, &dest))
- {
- LM_ERR("cannot get the destination parameter\n");
- return -1;
- }
- }
- init_dest_info(&dst);
- if (dest.len <= 0)
- {
- /*get next hop uri uri*/
- if (msg->dst_uri.len) {
- ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
- &next_hop);
- u = &next_hop;
- } else {
- ret = parse_sip_msg_uri(msg);
- u = &msg->parsed_uri;
- }
- if (ret<0) {
- LM_ERR("send() - bad_uri dropping packet\n");
- ret=E_BUG;
- goto error;
- }
- } else {
- u = &next_hop;
- u->port_no = 5060;
- u->host = dest;
- /* detect ipv6 */
- p = memchr(dest.s, ']', dest.len);
- if (p) {
- p++;
- p = memchr(p, ':', dest.s + dest.len - p);
- } else {
- p = memchr(dest.s, ':', dest.len);
- }
- if (p)
- {
- u->host.len = p - dest.s;
- p++;
- u->port_no = str2s(p, dest.len - (p - dest.s), NULL);
- }
- }
- ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
- &dst.proto);
- if(ret!=0) {
- LM_ERR("failed to resolve [%.*s]\n", u->host.len,
- ZSW(u->host.s));
- ret=E_BUG;
- goto error;
- }
- dst.proto = proto;
- if (proto == PROTO_UDP)
- {
- dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
- if (dst.send_sock!=0){
- ret=udp_send(&dst, msg->buf, msg->len);
- }else{
- ret=-1;
- }
- }
- #ifdef USE_TCP
- else{
- /*tcp*/
- dst.id=0;
- ret=tcp_send(&dst, 0, msg->buf, msg->len);
- }
- #endif
- if (ret>=0) ret=1;
- error:
- return ret;
- }
- /**
- *
- */
- int corex_send_data(str *puri, str *pdata)
- {
- struct dest_info dst;
- sip_uri_t next_hop;
- int ret = 0;
- char proto;
- if(parse_uri(puri->s, puri->len, &next_hop)<0)
- {
- LM_ERR("bad dst sip uri <%.*s>\n", puri->len, puri->s);
- return -1;
- }
- init_dest_info(&dst);
- LM_DBG("sending data to sip uri <%.*s>\n", puri->len, puri->s);
- proto = next_hop.proto;
- if(sip_hostport2su(&dst.to, &next_hop.host, next_hop.port_no,
- &proto)!=0) {
- LM_ERR("failed to resolve [%.*s]\n", next_hop.host.len,
- ZSW(next_hop.host.s));
- return -1;
- }
- dst.proto = proto;
- if(dst.proto==PROTO_NONE) dst.proto = PROTO_UDP;
- if (dst.proto == PROTO_UDP)
- {
- dst.send_sock=get_send_socket(0, &dst.to, PROTO_UDP);
- if (dst.send_sock!=0) {
- ret=udp_send(&dst, pdata->s, pdata->len);
- } else {
- LM_ERR("no socket for dst sip uri <%.*s>\n", puri->len, puri->s);
- ret=-1;
- }
- }
- #ifdef USE_TCP
- else if(dst.proto == PROTO_TCP) {
- /*tcp*/
- dst.id=0;
- ret=tcp_send(&dst, 0, pdata->s, pdata->len);
- }
- #endif
- #ifdef USE_TLS
- else if(dst.proto == PROTO_TLS) {
- /*tls*/
- dst.id=0;
- ret=tcp_send(&dst, 0, pdata->s, pdata->len);
- }
- #endif
- #ifdef USE_SCTP
- else if(dst.proto == PROTO_SCTP) {
- /*sctp*/
- dst.send_sock=get_send_socket(0, &dst.to, PROTO_SCTP);
- if (dst.send_sock!=0) {
- ret=sctp_core_msg_send(&dst, pdata->s, pdata->len);
- } else {
- LM_ERR("no socket for dst sip uri <%.*s>\n", puri->len, puri->s);
- ret=-1;
- }
- }
- #endif
- else {
- LM_ERR("unknown proto [%d] for dst sip uri <%.*s>\n",
- dst.proto, puri->len, puri->s);
- ret=-1;
- }
- if (ret>=0) ret=1;
- return ret;
- }
|