sip_monitor.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. /*
  2. * SIP Monitoring Agent -- by amoizard@gmail.com
  3. *
  4. * This program is Free Software, released under the GNU General
  5. * Public License v2.0 http://www.gnu.org/licenses/gpl
  6. *
  7. * This program will monitor connection to a SIP proxy.
  8. *
  9. */
  10. #if !defined(WIN32)
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. #include <netdb.h>
  18. #include <syslog.h>
  19. #ifndef OSIP_MONOTHREAD
  20. #include <pthread.h>
  21. #endif
  22. #include <string.h>
  23. #ifdef __linux
  24. #include <signal.h>
  25. #endif
  26. #endif
  27. #include <sys/time.h>
  28. #include <osip2/osip_mt.h>
  29. #include <eXosip2/eXosip.h>
  30. #include <osip2/osip.h>
  31. #if !defined(WIN32)
  32. #define _GNU_SOURCE
  33. #include <getopt.h>
  34. #endif
  35. #define PROG_NAME "sip_monitor"
  36. #define SYSLOG_FACILITY LOG_DAEMON
  37. struct monitored_log {
  38. int log_level;
  39. int count;
  40. char log[1024];
  41. };
  42. static volatile int keepRunning = 2;
  43. static int debug = 0;
  44. static osip_list_t monitored_logs;
  45. static char error_reason[1024] = {'\0'};
  46. #ifdef __linux
  47. static void intHandler(int dummy) {
  48. keepRunning = 0;
  49. }
  50. #endif
  51. #if defined(WIN32)
  52. static void syslog_wrapper(int a, const char *fmt, ...) {
  53. va_list args;
  54. va_start(args, fmt);
  55. vfprintf(stdout, fmt, args);
  56. va_end(args);
  57. }
  58. #define LOG_INFO 0
  59. #define LOG_ERR 0
  60. #define LOG_WARNING 0
  61. #define LOG_DEBUG 0
  62. #elif defined(LOG_PERROR)
  63. /* If we can, we use syslog() to emit the debugging messages to stderr. */
  64. #define syslog_wrapper syslog
  65. #else
  66. #define syslog_wrapper(a, b...) \
  67. fprintf(stderr, b); \
  68. fprintf(stderr, "\n")
  69. #endif
  70. static void usage(void);
  71. static void usage(void) {
  72. printf(PROG_NAME
  73. " v%s\n"
  74. "\nUsage: " PROG_NAME
  75. " [required_options] [optional_options]\n"
  76. "\n[required_options]\n"
  77. " -r --proxy sip:proxyhost[:port]\n"
  78. " -u --from sip:user@host[:port]\n"
  79. "\n[optional_options]\n"
  80. " -d --daemon (fork in daemon mode)\n"
  81. " -s --syslogandconsole (output syslog to stderr)\n"
  82. " -v --verbose number (show exosip logs to stdout)\n"
  83. "\n[optional_sip_options]\n"
  84. " -U --username username (authentication username)\n"
  85. " -P --password password (authentication password)\n"
  86. " -o --outbound sip:proxyhost[:port] (outbound proxy)\n"
  87. " -t --transport UDP|TCP|TLS|DTLS (default UDP)\n"
  88. " -e --expiry number (default 0 second - ie: fetch bindings)\n"
  89. " -S --sslrootcapath /etc/path (default /etc/ssl/certs/)\n"
  90. "\n[very_optional_sip_options]\n"
  91. " -p --port number (default 0 - random)\n"
  92. " -c --contact sip:user@host[:port]\n"
  93. " -m --automasquerade (auto discover NAT IP:PORT)\n"
  94. "\n"
  95. " -h --help\n",
  96. eXosip_get_version());
  97. }
  98. typedef struct regparam_t {
  99. int regid;
  100. int expiry;
  101. int auth;
  102. } regparam_t;
  103. struct eXosip_t *context_eXosip;
  104. static void add_log(int level, char *_log) {
  105. osip_list_iterator_t it;
  106. struct monitored_log *ml;
  107. ml = (struct monitored_log *) osip_list_get_first(&monitored_logs, &it);
  108. while (ml != OSIP_SUCCESS) {
  109. if (ml != NULL && strcmp(ml->log, _log) == 0) {
  110. ml->count++;
  111. return;
  112. }
  113. ml = (struct monitored_log *) osip_list_get_next(&it);
  114. }
  115. ml = (struct monitored_log *) osip_malloc(sizeof(struct monitored_log));
  116. ml->log_level = level;
  117. ml->count = 1;
  118. snprintf(ml->log, sizeof(ml->log), "%s", _log);
  119. osip_list_add(&monitored_logs, ml, -1);
  120. }
  121. static void dump_logs() {
  122. while (!osip_list_eol(&monitored_logs, 0)) {
  123. struct monitored_log *ml = (struct monitored_log *) osip_list_get(&monitored_logs, 0);
  124. syslog_wrapper(ml->log_level, "[count=%i] %s", ml->count, ml->log);
  125. osip_list_remove(&monitored_logs, 0);
  126. osip_free(ml);
  127. }
  128. }
  129. #if defined(WIN32) || defined(__linux)
  130. #define HAVE_LOCALTIME
  131. #endif
  132. #define MAX_LENGTH_TR 2024
  133. static void __osip_trace_func(const char *fi, int li, osip_trace_level_t level, const char *chfr, va_list args) {
  134. char time_buffer[80] = {'\0'};
  135. #if defined(HAVE_LOCALTIME)
  136. {
  137. time_t timestamp;
  138. struct timeval now;
  139. struct tm *ptm;
  140. #ifdef __USE_POSIX
  141. struct tm local_tm;
  142. #endif
  143. int tenths_ms;
  144. osip_gettimeofday(&now, NULL);
  145. timestamp = now.tv_sec;
  146. tenths_ms = now.tv_usec / (100L);
  147. #ifdef __USE_POSIX
  148. ptm = localtime_r(&timestamp, &local_tm);
  149. #else
  150. ptm = localtime(&timestamp);
  151. #endif
  152. snprintf(time_buffer, 80, "%04d-%02d-%02d %02d:%02d:%02d.%04d", 1900 + ptm->tm_year, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, tenths_ms);
  153. }
  154. #endif
  155. {
  156. char buffer[MAX_LENGTH_TR];
  157. int in = 0;
  158. memset(buffer, 0, sizeof(buffer));
  159. if (level == OSIP_FATAL) {
  160. in = snprintf(buffer, MAX_LENGTH_TR - 1, "| FATAL | %s <%10.10s:%5i> ", time_buffer, fi, li);
  161. } else if (level == OSIP_BUG) {
  162. in = snprintf(buffer, MAX_LENGTH_TR - 1, "| BUG | %s <%10.10s:%5i> ", time_buffer, fi, li);
  163. } else if (level == OSIP_ERROR) {
  164. in = snprintf(buffer, MAX_LENGTH_TR - 1, "| ERROR | %s <%10.10s:%5i> ", time_buffer, fi, li);
  165. } else if (level == OSIP_WARNING) {
  166. in = snprintf(buffer, MAX_LENGTH_TR - 1, "|WARNING| %s <%10.10s:%5i> ", time_buffer, fi, li);
  167. } else if (level == OSIP_INFO1) {
  168. in = snprintf(buffer, MAX_LENGTH_TR - 1, "| INFO1 | %s <%10.10s:%5i> ", time_buffer, fi, li);
  169. } else if (level == OSIP_INFO2) {
  170. in = snprintf(buffer, MAX_LENGTH_TR - 1, "| INFO2 | %s <%10.10s:%5i> ", time_buffer, fi, li);
  171. } else if (level == OSIP_INFO3) {
  172. in = snprintf(buffer, MAX_LENGTH_TR - 1, "| INFO3 | %s <%10.10s:%5i> ", time_buffer, fi, li);
  173. } else if (level == OSIP_INFO4) {
  174. in = snprintf(buffer, MAX_LENGTH_TR - 1, "| INFO4 | %s <%10.10s:%5i> ", time_buffer, fi, li);
  175. }
  176. vsnprintf(buffer + in, MAX_LENGTH_TR - 1 - in, chfr, args);
  177. buffer[MAX_LENGTH_TR - 1] = '\0';
  178. if (debug > (int) level) {
  179. printf("%s", buffer);
  180. }
  181. if (strstr(buffer, "[getaddrinfo] dns") != NULL && strstr(buffer, "failure") != NULL) {
  182. char *tmp = strstr(buffer, "[getaddrinfo");
  183. add_log(LOG_ERR, tmp);
  184. if (error_reason[0] == '\0') {
  185. snprintf(error_reason, sizeof(error_reason), "%s", tmp);
  186. }
  187. } else if (strstr(buffer, "socket [") != NULL && strstr(buffer, "] connected")) {
  188. char *tmp = strstr(buffer, "socket [");
  189. add_log(LOG_ERR, tmp);
  190. } else if (strstr(buffer, "[ssl connect] [verification=") != NULL) {
  191. char *tmp = strstr(buffer, "[ssl connect] ");
  192. add_log(LOG_INFO, tmp);
  193. if (error_reason[0] == '\0') {
  194. if (strstr(buffer, "[ssl connect] [verification=ENABLED] [FAILURE") != NULL) {
  195. snprintf(error_reason, sizeof(error_reason), "%s", tmp);
  196. }
  197. }
  198. } else if (strstr(buffer, "[TLS] invalid depth[") != NULL) {
  199. char *tmp = strstr(buffer, "[TLS] invalid depth[");
  200. add_log(LOG_ERR, tmp);
  201. if (error_reason[0] == '\0') {
  202. snprintf(error_reason, sizeof(error_reason), "%s", tmp);
  203. }
  204. } else if (strstr(buffer, "cannot connect socket ") != NULL && strstr(buffer, "terminated") != NULL) {
  205. char *tmp = strstr(buffer, "cannot connect socket ");
  206. add_log(LOG_ERR, tmp);
  207. if (error_reason[0] == '\0') {
  208. snprintf(error_reason, sizeof(error_reason), "%s", tmp);
  209. }
  210. }
  211. }
  212. }
  213. #ifdef TEST_NAPTR
  214. static int _naptr_lookup(const char *sip_server, struct osip_naptr *naptr_lookup, int keep_in_cache) {
  215. osip_naptr_t *naptr_record;
  216. naptr_record = eXosip_dnsutils_naptr(context_eXosip, sip_server, "sip", "tcp", keep_in_cache);
  217. if (naptr_record != NULL) {
  218. while (1) {
  219. /* 1: make sure there is no pending DNS */
  220. eXosip_dnsutils_dns_process(naptr_record, 1);
  221. if (naptr_record->naptr_state == OSIP_NAPTR_STATE_NAPTRDONE || naptr_record->naptr_state == OSIP_NAPTR_STATE_SRVINPROGRESS) {
  222. eXosip_dnsutils_dns_process(naptr_record, 1);
  223. }
  224. if (naptr_record->naptr_state == OSIP_NAPTR_STATE_UNKNOWN) {
  225. /* fallback to DNS A */
  226. /* should never happen? */
  227. eXosip_dnsutils_release(naptr_record);
  228. return OSIP_NOTFOUND;
  229. } else if (naptr_record->naptr_state == OSIP_NAPTR_STATE_INPROGRESS) {
  230. /* 2: keep waiting (naptr answer not received) */
  231. osip_usleep(10000);
  232. continue;
  233. } else if (naptr_record->naptr_state == OSIP_NAPTR_STATE_NAPTRDONE) {
  234. /* 3: keep waiting (naptr answer received/no srv answer received) */
  235. osip_usleep(1000);
  236. continue;
  237. } else if (naptr_record->naptr_state == OSIP_NAPTR_STATE_SRVINPROGRESS) {
  238. /* 3: keep waiting (naptr answer received/no srv answer received) */
  239. osip_usleep(1000);
  240. continue;
  241. } else if (naptr_record->naptr_state == OSIP_NAPTR_STATE_SRVDONE) {
  242. /* 4: check if we have the one we want... */
  243. if (naptr_lookup != NULL) {
  244. memcpy(naptr_lookup, naptr_record, sizeof(struct osip_naptr));
  245. }
  246. eXosip_dnsutils_release(naptr_record);
  247. return OSIP_SUCCESS;
  248. } else if (naptr_record->naptr_state == OSIP_NAPTR_STATE_NOTSUPPORTED) {
  249. /* 5: fallback to DNS A */
  250. eXosip_dnsutils_release(naptr_record);
  251. return OSIP_NOTFOUND;
  252. } else if (naptr_record->naptr_state == OSIP_NAPTR_STATE_RETRYLATER) {
  253. /* 5: fallback to DNS A */
  254. eXosip_dnsutils_release(naptr_record);
  255. return OSIP_TIMEOUT;
  256. }
  257. }
  258. }
  259. return -1;
  260. }
  261. static int _resolv_naptr(const char *domain) {
  262. struct timeval time_start;
  263. struct timeval time_end;
  264. struct timeval time_sub;
  265. int err;
  266. struct osip_naptr naptr_lookup;
  267. osip_gettimeofday(&time_start, NULL);
  268. memset(&naptr_lookup, 0, sizeof(struct osip_naptr));
  269. err = _naptr_lookup(domain, &naptr_lookup, 1);
  270. if (err == OSIP_SUCCESS) {
  271. if (naptr_lookup.sipenum_record.name[0] != '\0') {
  272. /* enum resolved: */
  273. syslog_wrapper(LOG_INFO, "ENUM: %s -> %s", domain, naptr_lookup.sipenum_record.name);
  274. } else {
  275. struct osip_srv_record *best = NULL;
  276. if (naptr_lookup.sipudp_record.srventry[0].port > 0) {
  277. best = &naptr_lookup.sipudp_record;
  278. } else if (naptr_lookup.siptcp_record.srventry[0].port > 0) {
  279. best = &naptr_lookup.siptcp_record;
  280. } else if (naptr_lookup.siptls_record.srventry[0].port > 0) {
  281. best = &naptr_lookup.siptls_record;
  282. }
  283. if (best != NULL) {
  284. if (naptr_lookup.siptcp_record.srventry[0].port > 0) {
  285. if (naptr_lookup.siptcp_record.order <= best->order) {
  286. best = &naptr_lookup.siptcp_record;
  287. }
  288. }
  289. if (naptr_lookup.siptls_record.srventry[0].port > 0) {
  290. if (naptr_lookup.siptls_record.order <= best->order) {
  291. best = &naptr_lookup.siptls_record;
  292. }
  293. }
  294. osip_gettimeofday(&time_end, NULL);
  295. osip_timersub(&time_end, &time_start, &time_sub);
  296. syslog_wrapper(LOG_INFO, "NAPTR REPORT:[SUCCESS] [duration:%li,%03lis] best service for %s -> [%s] [%s:%i]", time_sub.tv_sec, time_sub.tv_usec / 1000, naptr_lookup.domain, best->protocol, best->srventry[0].srv, best->srventry[0].port);
  297. return 0;
  298. }
  299. }
  300. }
  301. osip_gettimeofday(&time_end, NULL);
  302. osip_timersub(&time_end, &time_start, &time_sub);
  303. syslog_wrapper(LOG_ERR, "NAPTR REPORT:[FAILURE] [duration:%li,%03lis] no NAPTR/no SRV record for %s", time_sub.tv_sec, time_sub.tv_usec / 1000, domain);
  304. return 0;
  305. }
  306. #endif
  307. static int _am_option_route_add_lr(const char *orig_route, char *dst_route, int dst_route_size) {
  308. osip_route_t *route_header = NULL;
  309. char *new_route = NULL;
  310. const char *tmp;
  311. const char *tmp2;
  312. int i;
  313. memset(dst_route, '\0', dst_route_size);
  314. if (orig_route == NULL || orig_route[0] == '\0')
  315. return 0;
  316. tmp = strstr(orig_route, "sip:");
  317. tmp2 = strstr(orig_route, "sips:");
  318. if (tmp == NULL && tmp2 == NULL) {
  319. snprintf(dst_route, dst_route_size, "<sip:%s;lr>", orig_route);
  320. return 0;
  321. }
  322. i = osip_route_init(&route_header);
  323. if (i != 0 || route_header == NULL)
  324. return OSIP_NOMEM;
  325. i = osip_route_parse(route_header, orig_route);
  326. if (i != 0 || route_header->url == NULL || route_header->url->host == NULL) {
  327. osip_route_free(route_header);
  328. snprintf(dst_route, dst_route_size, "%s", orig_route);
  329. return i;
  330. }
  331. tmp = strstr(orig_route, ";lr");
  332. if (tmp == NULL)
  333. osip_uri_uparam_add(route_header->url, osip_strdup("lr"), NULL);
  334. i = osip_route_to_str(route_header, &new_route);
  335. osip_route_free(route_header);
  336. if (i != 0 || new_route == NULL) {
  337. return i;
  338. }
  339. snprintf(dst_route, dst_route_size, "%s", new_route);
  340. osip_free(new_route);
  341. return 0;
  342. }
  343. static int _prepend_route(osip_message_t *sip, const char *hvalue) {
  344. osip_route_t *route;
  345. int i;
  346. char outbound_route[256];
  347. if (hvalue == NULL || hvalue[0] == '\0')
  348. return OSIP_SUCCESS;
  349. memset(outbound_route, '\0', sizeof(outbound_route));
  350. i = _am_option_route_add_lr(hvalue, outbound_route, sizeof(outbound_route));
  351. if (i != 0)
  352. return i;
  353. i = osip_route_init(&route);
  354. if (i != 0)
  355. return i;
  356. i = osip_route_parse(route, outbound_route);
  357. if (i != 0) {
  358. osip_route_free(route);
  359. return i;
  360. }
  361. sip->message_property = 2;
  362. osip_list_add(&sip->routes, route, 0);
  363. return OSIP_SUCCESS;
  364. }
  365. int main(int argc, char *argv[]) {
  366. int exit_code = 1;
  367. int c;
  368. int port = 0;
  369. char *contact = NULL;
  370. char *fromuser = NULL;
  371. int automasquerade = 0;
  372. char *proxy = NULL;
  373. char *outbound = NULL;
  374. char transport[5];
  375. struct servent *service;
  376. char *username = NULL;
  377. char *password = NULL;
  378. char sslrootcapath[1024];
  379. struct regparam_t regparam = {0, -1, 0};
  380. int fork = 0;
  381. int log_perror = 0;
  382. int err;
  383. char prog_name[32];
  384. int optval;
  385. struct timeval time_start;
  386. struct timeval time_end;
  387. struct timeval time_sub;
  388. snprintf(prog_name, sizeof(prog_name), "%s (%s)", PROG_NAME, eXosip_get_version());
  389. #ifdef SIGPIPE
  390. signal(SIGPIPE, SIG_IGN);
  391. #endif
  392. #ifdef __linux
  393. signal(SIGINT, intHandler);
  394. #endif
  395. snprintf(transport, sizeof(transport), "%s", "UDP");
  396. snprintf(sslrootcapath, sizeof(sslrootcapath), "%s", "/etc/ssl/certs/");
  397. for (;;) {
  398. #define short_options "du:r:U:P:o:S:t:p:c:e:mv:sh"
  399. #ifdef _GNU_SOURCE
  400. int option_index = 0;
  401. static struct option long_options[] = {{"deamon", no_argument, NULL, 'd'},
  402. {"from", required_argument, NULL, 'u'},
  403. {"proxy", required_argument, NULL, 'r'},
  404. {"username", required_argument, NULL, 'U'},
  405. {"password", required_argument, NULL, 'P'},
  406. {"outbound", required_argument, NULL, 'o'},
  407. {"sslrootcapath", required_argument, NULL, 'S'},
  408. {"transport", required_argument, NULL, 't'},
  409. {"port", required_argument, NULL, 'p'},
  410. {"contact", required_argument, NULL, 'c'},
  411. {"expiry", required_argument, NULL, 'e'},
  412. {"automasquerade", no_argument, NULL, 'm'},
  413. {"syslogandconsole", no_argument, NULL, 's'},
  414. {"verbose", required_argument, NULL, 'v'},
  415. {"help", no_argument, NULL, 'h'},
  416. {NULL, 0, NULL, 0}};
  417. c = getopt_long(argc, argv, short_options, long_options, &option_index);
  418. #else
  419. c = getopt(argc, argv, short_options);
  420. #endif
  421. if (c == -1) {
  422. break;
  423. }
  424. switch (c) {
  425. case 'c':
  426. contact = optarg;
  427. break;
  428. case 'd':
  429. fork = 1;
  430. break;
  431. case 'v':
  432. debug = atoi(optarg);
  433. break;
  434. case 's':
  435. #ifdef LOG_PERROR
  436. log_perror = LOG_PERROR;
  437. #endif
  438. break;
  439. case 'e':
  440. regparam.expiry = atoi(optarg);
  441. break;
  442. case 'm':
  443. automasquerade = 1;
  444. break;
  445. case 'h':
  446. usage();
  447. exit(0);
  448. case 'p':
  449. service = getservbyname(optarg, "udp");
  450. if (service) {
  451. port = ntohs(service->s_port);
  452. } else {
  453. port = atoi(optarg);
  454. }
  455. break;
  456. case 't':
  457. snprintf(transport, sizeof(transport), "%s", optarg);
  458. break;
  459. case 'r':
  460. proxy = optarg;
  461. break;
  462. case 'u':
  463. fromuser = optarg;
  464. break;
  465. case 'U':
  466. username = optarg;
  467. break;
  468. case 'P':
  469. password = optarg;
  470. break;
  471. case 'o':
  472. outbound = optarg;
  473. break;
  474. case 'S':
  475. snprintf(sslrootcapath, sizeof(sslrootcapath), "%s", optarg);
  476. break;
  477. default:
  478. break;
  479. }
  480. }
  481. #ifdef LOG_PERROR
  482. openlog(PROG_NAME, LOG_PID | log_perror, SYSLOG_FACILITY);
  483. #endif
  484. syslog_wrapper(LOG_INFO, "%s up and running [testing on [%s] REGISTER [%s] From: [%s]%s%s%s %s%s%s", prog_name, transport, proxy, fromuser, (username && password) ? " Username: [" : "", (username && password) ? username : "",
  485. (username && password) ? ":*****]" : "", outbound? "Route: [" : "", outbound? outbound : "", outbound ? "]" : "");
  486. if (!proxy || !fromuser || strlen(proxy) < 7 || strlen(fromuser) < 7) {
  487. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] missing or broken mandatory parameter", transport);
  488. usage();
  489. exit(1);
  490. }
  491. if (osip_strcasecmp(transport, "UDP") != 0 && osip_strcasecmp(transport, "TCP") != 0 && osip_strcasecmp(transport, "TLS") != 0 && osip_strcasecmp(transport, "DTLS") != 0) {
  492. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] wrong transport parameter", transport);
  493. usage();
  494. exit(1);
  495. }
  496. if (fork) {
  497. err = daemon(1, 0);
  498. if (err < 0) {
  499. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] daemon mode failed", transport);
  500. exit(1);
  501. }
  502. }
  503. osip_list_init(&monitored_logs);
  504. osip_trace_initialize_func(TRACE_LEVEL6, __osip_trace_func);
  505. context_eXosip = eXosip_malloc();
  506. err = eXosip_init(context_eXosip);
  507. if (err) {
  508. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] eXosip_init failure [%i]", transport, err);
  509. dump_logs();
  510. exit(1);
  511. }
  512. eXosip_set_user_agent(context_eXosip, prog_name);
  513. if (username && password) {
  514. err = eXosip_add_authentication_info(context_eXosip, username, username, password, NULL, NULL);
  515. if (err) {
  516. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] cannot add credential [%i]", transport, err);
  517. eXosip_quit(context_eXosip);
  518. osip_free(context_eXosip);
  519. dump_logs();
  520. exit(1);
  521. }
  522. }
  523. optval = 1;
  524. eXosip_set_option(context_eXosip, EXOSIP_OPT_SET_TLS_VERIFY_CERTIFICATE, &optval);
  525. {
  526. eXosip_tls_ctx_t tls_description;
  527. memset(&tls_description, 0, sizeof(eXosip_tls_ctx_t));
  528. snprintf(tls_description.root_ca_cert, sizeof(tls_description.root_ca_cert), "%s", sslrootcapath);
  529. eXosip_set_option(context_eXosip, EXOSIP_OPT_SET_TLS_CERTIFICATES_INFO, &tls_description);
  530. }
  531. optval = automasquerade;
  532. eXosip_set_option(context_eXosip, EXOSIP_OPT_AUTO_MASQUERADE_CONTACT, &optval);
  533. if (automasquerade) {
  534. syslog_wrapper(LOG_INFO, "automasquerade enabled");
  535. }
  536. #ifdef TEST_NAPTR
  537. if (osip_strncasecmp(proxy, "sip:", 4) == 0) {
  538. _resolv_naptr(proxy + 4);
  539. } else if (osip_strncasecmp(proxy, "sips:", 4) == 0) {
  540. _resolv_naptr(proxy + 4);
  541. }
  542. #endif
  543. osip_gettimeofday(&time_start, NULL);
  544. err = -1;
  545. if (osip_strcasecmp(transport, "UDP") == 0) {
  546. err = eXosip_listen_addr(context_eXosip, IPPROTO_UDP, NULL, port, AF_INET, 0);
  547. } else if (osip_strcasecmp(transport, "TCP") == 0) {
  548. err = eXosip_listen_addr(context_eXosip, IPPROTO_TCP, NULL, port, AF_INET, 0);
  549. } else if (osip_strcasecmp(transport, "TLS") == 0) {
  550. err = eXosip_listen_addr(context_eXosip, IPPROTO_TCP, NULL, port, AF_INET, 1);
  551. } else if (osip_strcasecmp(transport, "DTLS") == 0) {
  552. err = eXosip_listen_addr(context_eXosip, IPPROTO_UDP, NULL, port, AF_INET, 1);
  553. }
  554. if (err) {
  555. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] cannot prepare sip network layer [%i]", transport, err);
  556. eXosip_quit(context_eXosip);
  557. osip_free(context_eXosip);
  558. dump_logs();
  559. exit(1);
  560. }
  561. {
  562. osip_message_t *reg = NULL;
  563. if (contact != NULL && regparam.expiry == -1) {
  564. regparam.expiry = 300;
  565. }
  566. eXosip_lock(context_eXosip);
  567. if (contact == NULL && regparam.expiry == -1) {
  568. regparam.regid = eXosip_register_build_initial_register(context_eXosip, fromuser, proxy, contact, 0, &reg);
  569. } else {
  570. regparam.regid = eXosip_register_build_initial_register(context_eXosip, fromuser, proxy, contact, regparam.expiry, &reg);
  571. }
  572. if (regparam.regid < 1) {
  573. eXosip_unlock(context_eXosip);
  574. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] cannot prepare sip REGISTER [%i]", transport, err);
  575. eXosip_quit(context_eXosip);
  576. osip_free(context_eXosip);
  577. dump_logs();
  578. exit(1);
  579. }
  580. _prepend_route(reg, outbound);
  581. if (contact == NULL && regparam.expiry == -1) {
  582. int pos = 0;
  583. while (!osip_list_eol(&reg->contacts, pos)) {
  584. osip_contact_t *co;
  585. co = (osip_contact_t *) osip_list_get(&reg->contacts, pos);
  586. osip_list_remove(&reg->contacts, pos);
  587. osip_contact_free(co);
  588. }
  589. }
  590. err = eXosip_register_send_register(context_eXosip, regparam.regid, reg);
  591. eXosip_unlock(context_eXosip);
  592. if (err != 0) {
  593. syslog_wrapper(LOG_ERR, "REGISTRATION REPORT:[FAILURE] [%s][duration:0,000s] cannot send sip REGISTER [%i]", transport, err);
  594. eXosip_quit(context_eXosip);
  595. osip_free(context_eXosip);
  596. dump_logs();
  597. exit(1);
  598. }
  599. }
  600. exit_code = 1;
  601. for (; keepRunning;) {
  602. eXosip_event_t *event;
  603. if (!(event = eXosip_event_wait(context_eXosip, 0, 1))) {
  604. #ifdef OSIP_MONOTHREAD
  605. eXosip_execute(context_eXosip);
  606. #endif
  607. eXosip_lock(context_eXosip);
  608. eXosip_automatic_action(context_eXosip);
  609. eXosip_unlock(context_eXosip);
  610. osip_usleep(10000);
  611. continue;
  612. }
  613. #ifdef OSIP_MONOTHREAD
  614. eXosip_execute(context_eXosip);
  615. #endif
  616. eXosip_lock(context_eXosip);
  617. eXosip_automatic_action(context_eXosip);
  618. switch (event->type) {
  619. case EXOSIP_REGISTRATION_SUCCESS:
  620. osip_gettimeofday(&time_end, NULL);
  621. osip_timersub(&time_end, &time_start, &time_sub);
  622. dump_logs();
  623. syslog_wrapper(LOG_INFO, "REGISTRATION REPORT:[SUCCESS] [%s][duration:%li,%03lis] REGISTER [%i][%s]", transport, time_sub.tv_sec, time_sub.tv_usec / 1000, event->response->status_code, event->response->reason_phrase);
  624. keepRunning = 0;
  625. exit_code = 0;
  626. break;
  627. case EXOSIP_REGISTRATION_FAILURE:
  628. osip_gettimeofday(&time_end, NULL);
  629. osip_timersub(&time_end, &time_start, &time_sub);
  630. dump_logs();
  631. if (event->response == NULL) {
  632. syslog_wrapper(LOG_INFO, "REGISTRATION REPORT:[FAILURE] [%s][duration:%li,%03lis] REGISTER [408][ ] err=%s", transport, time_sub.tv_sec, time_sub.tv_usec / 1000, error_reason[0] == '\0' ? "no answer" : error_reason);
  633. keepRunning = 0;
  634. } else {
  635. if (event->response->status_code == 401 || event->response->status_code == 407) {
  636. osip_authorization_t *auth = NULL;
  637. err = osip_message_get_authorization(event->request, 0, &auth);
  638. if (err < 0) {
  639. keepRunning--;
  640. if (keepRunning == 0) {
  641. syslog_wrapper(LOG_INFO, "REGISTRATION REPORT:[FAILURE] [%s][duration:%li,%03lis] REGISTER [%i][%s] err=no password or unsupported algorithm", transport, time_sub.tv_sec, time_sub.tv_usec / 1000, event->response->status_code,
  642. event->response->reason_phrase);
  643. } else {
  644. syslog_wrapper(LOG_INFO, "[%s][duration:%li,%03lis] REGISTER [%i][%s]", transport, time_sub.tv_sec, time_sub.tv_usec / 1000, event->response->status_code, event->response->reason_phrase);
  645. }
  646. } else {
  647. syslog_wrapper(LOG_INFO, "REGISTRATION REPORT:[FAILURE] [%s][duration:%li,%03lis] REGISTER [%i][%s] - err=bad password", transport, time_sub.tv_sec, time_sub.tv_usec / 1000, event->response->status_code, event->response->reason_phrase);
  648. keepRunning = 0; /* most probably a bad password */
  649. }
  650. } else {
  651. syslog_wrapper(LOG_INFO, "REGISTRATION REPORT:[FAILURE] [%s][duration:%li,%03lis] REGISTER [%i][%s] err=%s", transport, time_sub.tv_sec, time_sub.tv_usec / 1000, event->response->status_code, event->response->reason_phrase,
  652. event->response->reason_phrase);
  653. keepRunning = 0;
  654. }
  655. }
  656. break;
  657. case EXOSIP_CALL_INVITE: {
  658. osip_message_t *answer;
  659. int i;
  660. i = eXosip_call_build_answer(context_eXosip, event->tid, 405, &answer);
  661. if (i != 0) {
  662. syslog_wrapper(LOG_ERR, "failed to reject INVITE");
  663. break;
  664. }
  665. osip_free(answer->reason_phrase);
  666. answer->reason_phrase = osip_strdup("No Support for Incoming Calls");
  667. i = eXosip_call_send_answer(context_eXosip, event->tid, 405, answer);
  668. if (i != 0) {
  669. syslog_wrapper(LOG_ERR, "failed to reject INVITE");
  670. break;
  671. }
  672. syslog_wrapper(LOG_INFO, "INVITE rejected with 405");
  673. break;
  674. }
  675. case EXOSIP_MESSAGE_NEW: {
  676. osip_message_t *answer;
  677. int i;
  678. i = eXosip_message_build_answer(context_eXosip, event->tid, 405, &answer);
  679. if (i != 0) {
  680. syslog_wrapper(LOG_ERR, "failed to reject %s", event->request->sip_method);
  681. break;
  682. }
  683. i = eXosip_message_send_answer(context_eXosip, event->tid, 405, answer);
  684. if (i != 0) {
  685. syslog_wrapper(LOG_ERR, "failed to reject %s", event->request->sip_method);
  686. break;
  687. }
  688. syslog_wrapper(LOG_INFO, "%s rejected with 405", event->request->sip_method);
  689. break;
  690. }
  691. case EXOSIP_IN_SUBSCRIPTION_NEW: {
  692. osip_message_t *answer;
  693. int i;
  694. i = eXosip_insubscription_build_answer(context_eXosip, event->tid, 405, &answer);
  695. if (i != 0) {
  696. syslog_wrapper(LOG_ERR, "failed to reject %s", event->request->sip_method);
  697. break;
  698. }
  699. i = eXosip_insubscription_send_answer(context_eXosip, event->tid, 405, answer);
  700. if (i != 0) {
  701. syslog_wrapper(LOG_ERR, "failed to reject %s", event->request->sip_method);
  702. break;
  703. }
  704. syslog_wrapper(LOG_INFO, "%s rejected with 405", event->request->sip_method);
  705. break;
  706. }
  707. case EXOSIP_CALL_CLOSED:
  708. case EXOSIP_CALL_RELEASED:
  709. break;
  710. default:
  711. syslog_wrapper(LOG_DEBUG, "received unknown eXosip event (type, did, cid) = (%d, %d, %d)", event->type, event->did, event->cid);
  712. }
  713. eXosip_unlock(context_eXosip);
  714. eXosip_event_free(event);
  715. }
  716. eXosip_quit(context_eXosip);
  717. osip_free(context_eXosip);
  718. dump_logs();
  719. return exit_code;
  720. }