corex_lib.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * $Id$
  3. *
  4. * Copyright (C) 2011 Daniel-Constantin Mierla (asipto.com)
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Permission to use, copy, modify, and distribute this software for any
  9. * purpose with or without fee is hereby granted, provided that the above
  10. * copyright notice and this permission notice appear in all copies.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  13. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  15. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  16. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  18. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19. *
  20. */
  21. #include <stdio.h>
  22. #include <unistd.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "../../dprint.h"
  26. #include "../../dset.h"
  27. #include "../../forward.h"
  28. #include "../../parser/parse_uri.h"
  29. #include "../../resolve.h"
  30. #include "corex_lib.h"
  31. /**
  32. * append new branches with generic parameters
  33. */
  34. int corex_append_branch(sip_msg_t *msg, gparam_t *pu, gparam_t *pq)
  35. {
  36. str uri = {0};
  37. str qv = {0};
  38. int ret = 0;
  39. qvalue_t q = Q_UNSPECIFIED;
  40. flag_t branch_flags = 0;
  41. if (pu!=NULL)
  42. {
  43. if(fixup_get_svalue(msg, pu, &uri)!=0)
  44. {
  45. LM_ERR("cannot get the URI parameter\n");
  46. return -1;
  47. }
  48. }
  49. if (pq!=NULL)
  50. {
  51. if(fixup_get_svalue(msg, pq, &qv)!=0)
  52. {
  53. LM_ERR("cannot get the Q parameter\n");
  54. return -1;
  55. }
  56. if(qv.len>0 && str2q(&q, qv.s, qv.len)<0)
  57. {
  58. LM_ERR("cannot parse the Q parameter\n");
  59. return -1;
  60. }
  61. }
  62. getbflagsval(0, &branch_flags);
  63. ret = append_branch(msg, (uri.len>0)?&uri:0, &msg->dst_uri,
  64. &msg->path_vec, q, branch_flags,
  65. msg->force_send_socket, 0, 0, 0, 0);
  66. if(uri.len<=0)
  67. {
  68. /* reset all branch attributes if r-uri was shifted to branch */
  69. reset_force_socket(msg);
  70. setbflagsval(0, 0);
  71. if(msg->dst_uri.s!=0)
  72. pkg_free(msg->dst_uri.s);
  73. msg->dst_uri.s = 0;
  74. msg->dst_uri.len = 0;
  75. /* 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*/
  76. if (!(msg->msg_flags&FL_SHM_CLONE)) {
  77. if(msg->path_vec.s!=0)
  78. pkg_free(msg->path_vec.s);
  79. msg->path_vec.s = 0;
  80. msg->path_vec.len = 0;
  81. }
  82. }
  83. return ret;
  84. }
  85. typedef struct corex_alias {
  86. str alias;
  87. unsigned short port;
  88. unsigned short proto;
  89. int flags;
  90. struct corex_alias* next;
  91. } corex_alias_t;
  92. static corex_alias_t *_corex_alias_list = NULL;
  93. int corex_add_alias_subdomains(char* aliasval)
  94. {
  95. char *p = NULL;
  96. corex_alias_t ta;
  97. corex_alias_t *na;
  98. memset(&ta, 0, sizeof(corex_alias_t));
  99. p = strchr(aliasval, ':');
  100. if(p==NULL) {
  101. /* only hostname */
  102. ta.alias.s = aliasval;
  103. ta.alias.len = strlen(aliasval);
  104. goto done;
  105. }
  106. if((p-aliasval)==3 || (p-aliasval)==4) {
  107. /* check if it is protocol */
  108. if((p-aliasval)==3 && strncasecmp(aliasval, "udp", 3)==0) {
  109. ta.proto = PROTO_UDP;
  110. } else if((p-aliasval)==3 && strncasecmp(aliasval, "tcp", 3)==0) {
  111. ta.proto = PROTO_TCP;
  112. } else if((p-aliasval)==3 && strncasecmp(aliasval, "tls", 3)==0) {
  113. ta.proto = PROTO_TLS;
  114. } else if((p-aliasval)==4 && strncasecmp(aliasval, "sctp", 4)==0) {
  115. ta.proto = PROTO_SCTP;
  116. } else {
  117. /* use hostname */
  118. ta.alias.s = aliasval;
  119. ta.alias.len = p - aliasval;
  120. }
  121. }
  122. if(ta.alias.len==0) {
  123. p++;
  124. if(p>=aliasval+strlen(aliasval))
  125. goto error;
  126. ta.alias.s = p;
  127. p = strchr(ta.alias.s, ':');
  128. if(p==NULL) {
  129. ta.alias.len = strlen(ta.alias.s);
  130. goto done;
  131. }
  132. }
  133. /* port */
  134. p++;
  135. if(p>=aliasval+strlen(aliasval))
  136. goto error;
  137. ta.port = str2s(p, strlen(p), NULL);
  138. done:
  139. if(ta.alias.len==0)
  140. goto error;
  141. na = (corex_alias_t*)pkg_malloc(sizeof(corex_alias_t));
  142. if(na==NULL) {
  143. LM_ERR("no memory for adding alias subdomains: %s\n", aliasval);
  144. return -1;
  145. }
  146. memcpy(na, &ta, sizeof(corex_alias_t));
  147. na->next = _corex_alias_list;
  148. _corex_alias_list = na;
  149. return 0;
  150. error:
  151. LM_ERR("error adding alias subdomains: %s\n", aliasval);
  152. return -1;
  153. }
  154. int corex_check_self(str* host, unsigned short port, unsigned short proto)
  155. {
  156. corex_alias_t *ta;
  157. for(ta=_corex_alias_list; ta; ta=ta->next) {
  158. if(host->len<ta->alias.len)
  159. continue;
  160. if(ta->port!=0 && port!=0 && ta->port!=port)
  161. continue;
  162. if(ta->proto!=0 && proto!=0 && ta->proto!=proto)
  163. continue;
  164. if(host->len==ta->alias.len
  165. && strncasecmp(host->s, ta->alias.s, host->len)==0) {
  166. /* match domain */
  167. LM_DBG("check self domain match: %d:%.*s:%d\n", (int)ta->port,
  168. ta->alias.len, ta->alias.s, (int)ta->proto);
  169. return 1;
  170. }
  171. if(strncasecmp(ta->alias.s, host->s + host->len - ta->alias.len,
  172. ta->alias.len)==0) {
  173. if(host->s[host->len - ta->alias.len - 1]=='.') {
  174. /* match sub-domain */
  175. LM_DBG("check self sub-domain match: %d:%.*s:%d\n", (int)ta->port,
  176. ta->alias.len, ta->alias.s, (int)ta->proto);
  177. return 1;
  178. }
  179. }
  180. }
  181. return 0; /* no match */
  182. }
  183. int corex_register_check_self(void)
  184. {
  185. if(_corex_alias_list==NULL)
  186. return 0;
  187. if (register_check_self_func(corex_check_self) <0 ) {
  188. LM_ERR("failed to register check self function\n");
  189. return -1;
  190. }
  191. return 0;
  192. }
  193. int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto)
  194. {
  195. str dest = {0};
  196. int ret = 0;
  197. struct sip_uri next_hop, *u;
  198. struct dest_info dst;
  199. char *p;
  200. if (pu)
  201. {
  202. if (fixup_get_svalue(msg, pu, &dest))
  203. {
  204. LM_ERR("cannot get the destination parameter\n");
  205. return -1;
  206. }
  207. }
  208. init_dest_info(&dst);
  209. if (dest.len <= 0)
  210. {
  211. /*get next hop uri uri*/
  212. if (msg->dst_uri.len) {
  213. ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
  214. &next_hop);
  215. u = &next_hop;
  216. } else {
  217. ret = parse_sip_msg_uri(msg);
  218. u = &msg->parsed_uri;
  219. }
  220. if (ret<0) {
  221. LM_ERR("send() - bad_uri dropping packet\n");
  222. ret=E_BUG;
  223. goto error;
  224. }
  225. } else {
  226. u = &next_hop;
  227. u->port_no = 5060;
  228. u->host = dest;
  229. /* detect ipv6 */
  230. p = memchr(dest.s, ']', dest.len);
  231. if (p) {
  232. p++;
  233. p = memchr(p, ':', dest.s + dest.len - p);
  234. } else {
  235. p = memchr(dest.s, ':', dest.len);
  236. }
  237. if (p)
  238. {
  239. u->host.len = p - dest.s;
  240. p++;
  241. u->port_no = str2s(p, dest.len - (p - dest.s), NULL);
  242. }
  243. }
  244. ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
  245. &dst.proto);
  246. if(ret!=0) {
  247. LM_ERR("failed to resolve [%.*s]\n", u->host.len,
  248. ZSW(u->host.s));
  249. ret=E_BUG;
  250. goto error;
  251. }
  252. dst.proto = proto;
  253. if (proto == PROTO_UDP)
  254. {
  255. dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
  256. if (dst.send_sock!=0){
  257. ret=udp_send(&dst, msg->buf, msg->len);
  258. }else{
  259. ret=-1;
  260. }
  261. }
  262. #ifdef USE_TCP
  263. else{
  264. /*tcp*/
  265. dst.id=0;
  266. ret=tcp_send(&dst, 0, msg->buf, msg->len);
  267. }
  268. #endif
  269. if (ret>=0) ret=1;
  270. error:
  271. return ret;
  272. }
  273. /**
  274. *
  275. */
  276. int corex_send_data(str *puri, str *pdata)
  277. {
  278. struct dest_info dst;
  279. sip_uri_t next_hop;
  280. int ret = 0;
  281. char proto;
  282. if(parse_uri(puri->s, puri->len, &next_hop)<0)
  283. {
  284. LM_ERR("bad dst sip uri <%.*s>\n", puri->len, puri->s);
  285. return -1;
  286. }
  287. init_dest_info(&dst);
  288. LM_DBG("sending data to sip uri <%.*s>\n", puri->len, puri->s);
  289. proto = next_hop.proto;
  290. if(sip_hostport2su(&dst.to, &next_hop.host, next_hop.port_no,
  291. &proto)!=0) {
  292. LM_ERR("failed to resolve [%.*s]\n", next_hop.host.len,
  293. ZSW(next_hop.host.s));
  294. return -1;
  295. }
  296. dst.proto = proto;
  297. if(dst.proto==PROTO_NONE) dst.proto = PROTO_UDP;
  298. if (dst.proto == PROTO_UDP)
  299. {
  300. dst.send_sock=get_send_socket(0, &dst.to, PROTO_UDP);
  301. if (dst.send_sock!=0) {
  302. ret=udp_send(&dst, pdata->s, pdata->len);
  303. } else {
  304. LM_ERR("no socket for dst sip uri <%.*s>\n", puri->len, puri->s);
  305. ret=-1;
  306. }
  307. }
  308. #ifdef USE_TCP
  309. else if(dst.proto == PROTO_TCP) {
  310. /*tcp*/
  311. dst.id=0;
  312. ret=tcp_send(&dst, 0, pdata->s, pdata->len);
  313. }
  314. #endif
  315. #ifdef USE_TLS
  316. else if(dst.proto == PROTO_TLS) {
  317. /*tls*/
  318. dst.id=0;
  319. ret=tcp_send(&dst, 0, pdata->s, pdata->len);
  320. }
  321. #endif
  322. #ifdef USE_SCTP
  323. else if(dst.proto == PROTO_SCTP) {
  324. /*sctp*/
  325. dst.send_sock=get_send_socket(0, &dst.to, PROTO_SCTP);
  326. if (dst.send_sock!=0) {
  327. ret=sctp_core_msg_send(&dst, pdata->s, pdata->len);
  328. } else {
  329. LM_ERR("no socket for dst sip uri <%.*s>\n", puri->len, puri->s);
  330. ret=-1;
  331. }
  332. }
  333. #endif
  334. else {
  335. LM_ERR("unknown proto [%d] for dst sip uri <%.*s>\n",
  336. dst.proto, puri->len, puri->s);
  337. ret=-1;
  338. }
  339. if (ret>=0) ret=1;
  340. return ret;
  341. }