You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

513 lines
16KB

  1. #include <memory>
  2. #include "sockutil.h"
  3. #include "aio-timeout.h"
  4. #include "sip-agent.h"
  5. #include "sip-uac.h"
  6. #include "sip-uas.h"
  7. #include "sip-message.h"
  8. #include "sip-transport.h"
  9. #include "sip-timer.h"
  10. #include "port/ip-route.h"
  11. #include "http-parser.h"
  12. #include "http-header-auth.h"
  13. #include "sys/thread.h"
  14. #include "sys/system.h"
  15. #include "sys/sync.hpp"
  16. #include "time64.h"
  17. #include "channel.h"
  18. #include "uri-parse.h"
  19. #include "cstringext.h"
  20. #include "base64.h"
  21. #include "md5.h"
  22. #include <stdint.h>
  23. #define LOOP 100
  24. #define NQUEUE 3
  25. #define NCONCURRENT 200
  26. #define CHANNEL_DONE ((void*)0xabcdef98)
  27. #define TRANSPORT_PACKET_LOST 20
  28. struct sip_tu_t
  29. {
  30. struct sip_agent_t* sip;
  31. struct channel_t* q[NQUEUE];
  32. struct sip_transport_t transport;
  33. int32_t count;
  34. };
  35. struct sip_agent_test_t
  36. {
  37. socket_t udp;
  38. bool running;
  39. struct sip_tu_t alice;
  40. struct sip_tu_t bob;
  41. };
  42. struct sip_packet_t
  43. {
  44. void* ptr;
  45. int len;
  46. };
  47. struct sip_task_t
  48. {
  49. struct sip_tu_t* self;
  50. struct sip_tu_t* peer;
  51. char from[64];
  52. char to[64];
  53. ThreadEvent event;
  54. struct sip_dialog_t* dialog;
  55. int32_t terminated;
  56. int32_t success;
  57. int32_t failed;
  58. };
  59. static struct sip_task_t s_alice_tasks[NCONCURRENT];
  60. static struct sip_task_t s_bob_tasks[NCONCURRENT];
  61. static struct sip_agent_test_t s_sip;
  62. static int sip_uac_transport_via(void* transport, const char* destination, char protocol[16], char local[128], char dns[128])
  63. {
  64. int r;
  65. char ip[65];
  66. u_short port;
  67. struct uri_t* uri;
  68. socklen_t addrlen;
  69. struct sockaddr_storage addr;
  70. // rfc3263 4.1 Selecting a Transport Protocol
  71. // 1. If the URI specifies a transport protocol in the transport parameter,
  72. // that transport protocol SHOULD be used. Otherwise, if no transport
  73. // protocol is specified, but the TARGET(maddr) is a numeric IP address,
  74. // the client SHOULD use UDP for a SIP URI, and TCP for a SIPS URI.
  75. // 2. if no transport protocol is specified, and the TARGET is not numeric,
  76. // but an explicit port is provided, the client SHOULD use UDP for a SIP URI,
  77. // and TCP for a SIPS URI
  78. // 3. Otherwise, if no transport protocol or port is specified, and the target
  79. // is not a numeric IP address, the client SHOULD perform a NAPTR query for
  80. // the domain in the URI.
  81. // The client SHOULD try the first record. If an attempt should fail, based on
  82. // the definition of failure in Section 4.3, the next SHOULD be tried, and if
  83. // that should fail, the next SHOULD be tried, and so on.
  84. addrlen = sizeof(addr);
  85. memset(&addr, 0, sizeof(addr));
  86. strcpy(protocol, "UDP");
  87. uri = uri_parse(destination, strlen(destination));
  88. if (!uri)
  89. return -1; // invalid uri
  90. // rfc3263 4-Client Usage (p5)
  91. // once a SIP server has successfully been contacted (success is defined below),
  92. // all retransmissions of the SIP request and the ACK for non-2xx SIP responses
  93. // to INVITE MUST be sent to the same host.
  94. // Furthermore, a CANCEL for a particular SIP request MUST be sent to the same
  95. // SIP server that the SIP request was delivered to.
  96. // TODO: sips port
  97. r = socket_addr_from(&addr, &addrlen, uri->host, uri->port ? uri->port : SIP_PORT);
  98. if (0 == r)
  99. {
  100. socket_addr_to((struct sockaddr*)&addr, addrlen, ip, &port);
  101. socket_getname(s_sip.udp, local, &port);
  102. r = ip_route_get(ip, local);
  103. if (0 == r)
  104. {
  105. dns[0] = 0;
  106. struct sockaddr_storage ss;
  107. socklen_t len = sizeof(ss);
  108. if (0 == socket_addr_from(&ss, &len, local, port))
  109. socket_addr_name((struct sockaddr*)&ss, len, dns, 128);
  110. if (SIP_PORT != port)
  111. snprintf(local + strlen(local), 128 - strlen(local), ":%hu", port);
  112. if (NULL == strchr(dns, '.'))
  113. snprintf(dns, 128, "%s", local); // don't have valid dns
  114. }
  115. else
  116. {
  117. assert(0);
  118. }
  119. }
  120. else
  121. {
  122. assert(0);
  123. }
  124. uri_free(uri);
  125. return r;
  126. }
  127. static int sip_uac_transport_send(void* param, const void* data, size_t bytes)
  128. {
  129. struct sip_task_t *task = (struct sip_task_t*)param;
  130. if ((rand() % 100) < TRANSPORT_PACKET_LOST)
  131. return 0; // packet lost
  132. int i = rand() % NQUEUE;
  133. sip_packet_t pkt;
  134. pkt.ptr = malloc(bytes);
  135. pkt.len = bytes;
  136. memcpy(pkt.ptr, data, bytes);
  137. char st[32];
  138. time64_format(time64_now(), "%04Y-%02M-%02D %02h:%02m:%02s", st);
  139. //printf("UAC: %s\n%.*s\n", st, bytes, (const char*)pkt.ptr);
  140. assert(0 == channel_push(task->peer->q[i], &pkt));
  141. return 0;
  142. }
  143. static int sip_uas_transport_send(void* param, const struct cstring_t* /*protocol*/, const struct cstring_t* /*url*/, const struct cstring_t* /*received*/, int /*rport*/, const void* data, int bytes)
  144. {
  145. assert(param == &s_sip.alice || param == &s_sip.bob);
  146. struct sip_tu_t* tu = (struct sip_tu_t*)param;
  147. struct sip_tu_t* peer = tu == &s_sip.alice ? &s_sip.bob : &s_sip.alice;
  148. if ((rand() % 100) < TRANSPORT_PACKET_LOST)
  149. return 0; // packet lost
  150. sip_packet_t pkt;
  151. pkt.ptr = malloc(bytes);
  152. pkt.len = bytes;
  153. memcpy(pkt.ptr, data, bytes);
  154. char st[32];
  155. time64_format(time64_now(), "%04Y-%02M-%02D %02h:%02m:%02s", st);
  156. //printf("UAS: %s\n%.*s\n", st, bytes, (const char*)pkt.ptr);
  157. int i = rand() % NQUEUE;
  158. assert(0 == channel_push(peer->q[i], &pkt));
  159. return 0;
  160. }
  161. static void sip_uac_task_ondestroy(void* param)
  162. {
  163. struct sip_task_t *task = (struct sip_task_t *)param;
  164. atomic_decrement32(&task->terminated);
  165. }
  166. static int sip_uac_onmessage(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  167. {
  168. assert(code >= 200 && code < 700);
  169. struct sip_task_t *task = (struct sip_task_t *)param;
  170. task->success += (code >= 200 && code < 300);
  171. task->failed += (code >= 300 && code < 700);
  172. task->event.Signal();
  173. return 0;
  174. }
  175. static void sip_uac_message_test(struct sip_task_t *task)
  176. {
  177. const char* msg = "<?xml version=\"1.0\"?><msg>Hello SIP</msg>";
  178. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_message(task->self->sip, task->from, task->to, sip_uac_onmessage, task), sip_uac_transaction_release);
  179. sip_uac_transaction_ondestroy(t.get(), sip_uac_task_ondestroy, task);
  180. sip_uac_add_header(t.get(), "Content-Type", "Application/xml");
  181. assert(0 == sip_uac_send(t.get(), msg, strlen(msg), &task->self->transport, task));
  182. assert(0 == task->event.Wait());
  183. }
  184. static int sip_uac_onregister(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  185. {
  186. assert(code >= 200 && code < 700);
  187. struct sip_task_t *task = (struct sip_task_t *)param;
  188. task->success += (code >= 200 && code < 300);
  189. task->failed += (code >= 300 && code < 700);
  190. task->event.Signal();
  191. return 0;
  192. }
  193. static void sip_uac_register_test(struct sip_task_t *task)
  194. {
  195. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_register(task->self->sip, task->from, "sip:127.0.0.1", 7200, sip_uac_onregister, task), sip_uac_transaction_release);
  196. sip_uac_transaction_ondestroy(t.get(), sip_uac_task_ondestroy, task);
  197. assert(0 == sip_uac_send(t.get(), NULL, 0, &task->self->transport, task));
  198. assert(0 == task->event.Wait());
  199. }
  200. static int sip_uac_oninvited(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
  201. {
  202. assert(code >= 100 && code < 700);
  203. if (code >= 200 && code < 700)
  204. {
  205. struct sip_task_t *task = (struct sip_task_t *)param;
  206. task->success += (code >= 200 && code < 300);
  207. task->failed += (code >= 300 && code < 700);
  208. assert(task->dialog == NULL);
  209. task->dialog = dialog;
  210. if (200 <= code && code < 300)
  211. {
  212. *session = NULL;
  213. sip_uac_ack(t, NULL, 0);
  214. }
  215. task->event.Signal();
  216. }
  217. return NULL;
  218. }
  219. static void sip_uac_invite_test(struct sip_task_t *task)
  220. {
  221. assert(task->dialog == NULL);
  222. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_invite(task->self->sip, task->from, task->to, sip_uac_oninvited, task), sip_uac_transaction_release);
  223. sip_uac_transaction_ondestroy(t.get(), sip_uac_task_ondestroy, task);
  224. assert(0 == sip_uac_send(t.get(), NULL, 0, &task->self->transport, task));
  225. assert(0 == task->event.Wait());
  226. }
  227. static int sip_uac_onbye(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  228. {
  229. assert(code >= 200 && code < 700);
  230. struct sip_task_t *task = (struct sip_task_t *)param;
  231. task->success += (code >= 200 && code < 300);
  232. task->failed += (code >= 300 && code < 700);
  233. assert(task->dialog);
  234. if ((code >= 200 && code < 300) || 481 == code)
  235. task->dialog = NULL;
  236. else
  237. printf("%s bye failed: %d\n", task->from, code);
  238. task->event.Signal();
  239. return 0;
  240. }
  241. static void sip_uac_bye_test(struct sip_task_t *task)
  242. {
  243. assert(task->dialog);
  244. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_bye(task->self->sip, task->dialog, sip_uac_onbye, task), sip_uac_transaction_release);
  245. sip_uac_transaction_ondestroy(t.get(), sip_uac_task_ondestroy, task);
  246. assert(0 == sip_uac_send(t.get(), NULL, 0, &task->self->transport, task));
  247. assert(0 == task->event.Wait());
  248. }
  249. static int STDCALL AliceThread(void* param)
  250. {
  251. struct sip_task_t* task = (struct sip_task_t*)param;
  252. for (int i = 0; i < LOOP; i++)
  253. {
  254. switch (rand() % 3)
  255. {
  256. case 0:
  257. atomic_increment32(&task->terminated);
  258. sip_uac_register_test(task);
  259. case 1:
  260. atomic_increment32(&task->terminated);
  261. sip_uac_message_test(task);
  262. case 2:
  263. atomic_increment32(&task->terminated);
  264. sip_uac_invite_test(task);
  265. while(task->dialog)
  266. {
  267. atomic_increment32(&task->terminated);
  268. sip_uac_bye_test(task);
  269. }
  270. }
  271. }
  272. while(task->terminated != 0)
  273. system_sleep(10);
  274. printf("%s done\n", task->from);
  275. return 0;
  276. }
  277. static void sip_uas_task_ondestroy(void* param)
  278. {
  279. struct sip_tu_t *tu = (struct sip_tu_t *)param;
  280. assert(atomic_decrement32(&tu->count) >= 0);
  281. }
  282. static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
  283. {
  284. *session = t;
  285. char contact[128];
  286. struct sip_tu_t* tu = (struct sip_tu_t*)param;
  287. atomic_increment32(&tu->count);
  288. sip_uas_transaction_ondestroy(t, sip_uas_task_ondestroy, param);
  289. sip_contact_write(&req->to, contact, contact+sizeof(contact));
  290. sip_uas_add_header(t, "Contact", contact);
  291. assert(0 == sip_uas_reply(t, 200, NULL, 0, param));
  292. return 0;
  293. }
  294. /// @param[in] code 0-ok, other-sip status code
  295. /// @return 0-ok, other-error
  296. static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
  297. {
  298. return 0;
  299. }
  300. /// on terminating a session(dialog)
  301. static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  302. {
  303. struct sip_tu_t* tu = (struct sip_tu_t*)param;
  304. atomic_increment32(&tu->count);
  305. sip_uas_transaction_ondestroy(t, sip_uas_task_ondestroy, param);
  306. return sip_uas_reply(t, 200, NULL, 0, param);
  307. }
  308. /// cancel a transaction(should be an invite transaction)
  309. static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  310. {
  311. struct sip_tu_t* tu = (struct sip_tu_t*)param;
  312. atomic_increment32(&tu->count);
  313. sip_uas_transaction_ondestroy(t, sip_uas_task_ondestroy, param);
  314. return sip_uas_reply(t, 200, NULL, 0, param);
  315. }
  316. /// @param[in] expires in seconds
  317. static int sip_uas_onregister(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const char* user, const char* location, int expires)
  318. {
  319. struct sip_tu_t* tu = (struct sip_tu_t*)param;
  320. atomic_increment32(&tu->count);
  321. sip_uas_transaction_ondestroy(t, sip_uas_task_ondestroy, param);
  322. return sip_uas_reply(t, 200, NULL, 0, param);
  323. }
  324. static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const void* payload, int bytes)
  325. {
  326. struct sip_tu_t* tu = (struct sip_tu_t*)param;
  327. atomic_increment32(&tu->count);
  328. sip_uas_transaction_ondestroy(t, sip_uas_task_ondestroy, param);
  329. return sip_uas_reply(t, 200, NULL, 0, param);
  330. }
  331. static int STDCALL InputThread(struct sip_tu_t* tu, int idx)
  332. {
  333. http_parser_t* parser = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
  334. while(channel_count(tu->q[idx]) > 0 || s_sip.running)
  335. {
  336. //int r = socket_recvfrom(test->udp, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &addrlen);
  337. sip_packet_t pkt;
  338. memset(&pkt, 0, sizeof(pkt));
  339. assert(0 == (sip_packet_t*)channel_pop(tu->q[idx], &pkt));
  340. if(pkt.ptr == CHANNEL_DONE)
  341. continue;
  342. int response = 0 == strncasecmp("SIP", (char*)pkt.ptr, 3) ? 1 : 0;
  343. http_parser_reset(parser, response ? HTTP_PARSER_RESPONSE : HTTP_PARSER_REQUEST);
  344. size_t n = pkt.len;
  345. assert(0 == http_parser_input(parser, pkt.ptr, &n));
  346. struct sip_message_t* msg = sip_message_create(response ? SIP_MESSAGE_REPLY : SIP_MESSAGE_REQUEST);
  347. assert(0 == sip_message_load(msg, parser));
  348. assert(0 == sip_agent_input(tu->sip, msg, tu));
  349. sip_message_destroy(msg);
  350. free(pkt.ptr);
  351. }
  352. http_parser_destroy(parser);
  353. return 0;
  354. }
  355. static int STDCALL AliceInputThread(void* param)
  356. {
  357. return InputThread(&s_sip.alice, (int)(intptr_t)param);
  358. }
  359. static int STDCALL BobInputThread(void* param)
  360. {
  361. return InputThread(&s_sip.bob, (int)(intptr_t)param);
  362. }
  363. extern "C" void sip_agent_test(void)
  364. {
  365. sip_timer_init();
  366. s_sip.alice.transport = {
  367. sip_uac_transport_via,
  368. sip_uac_transport_send,
  369. };
  370. s_sip.bob.transport = {
  371. sip_uac_transport_via,
  372. sip_uac_transport_send,
  373. };
  374. s_sip.running = true;
  375. struct sip_uas_handler_t handler;
  376. handler.onregister = sip_uas_onregister;
  377. handler.oninvite = sip_uas_oninvite;
  378. handler.onack = sip_uas_onack;
  379. handler.onbye = sip_uas_onbye;
  380. handler.oncancel = sip_uas_oncancel;
  381. handler.onmessage = sip_uas_onmessage;
  382. handler.send = sip_uas_transport_send;
  383. s_sip.udp = socket_udp();
  384. s_sip.alice.sip = sip_agent_create(&handler);
  385. s_sip.bob.sip = sip_agent_create(&handler);
  386. s_sip.alice.count = 0;
  387. s_sip.bob.count = 0;
  388. pthread_t worker[NQUEUE*2];
  389. for (int i = 0; i < NQUEUE; i++)
  390. {
  391. s_sip.alice.q[i] = channel_create(200, sizeof(struct sip_packet_t));
  392. s_sip.bob.q[i] = channel_create(200, sizeof(struct sip_packet_t));
  393. thread_create(&worker[2*i], AliceInputThread, (void*)(intptr_t)i); // alice
  394. thread_create(&worker[2*i+1], BobInputThread, (void*)(intptr_t)i); // bob
  395. }
  396. pthread_t bob[NCONCURRENT];
  397. pthread_t alice[NCONCURRENT];
  398. for (int i = 0; i < NCONCURRENT; i++)
  399. {
  400. s_alice_tasks[i].dialog = NULL;
  401. s_alice_tasks[i].self = &s_sip.alice;
  402. s_alice_tasks[i].peer = &s_sip.bob;
  403. s_alice_tasks[i].success = 0;
  404. s_alice_tasks[i].failed = 0;
  405. s_alice_tasks[i].terminated = 0;
  406. snprintf(s_alice_tasks[i].from, sizeof(s_alice_tasks[i].from), "sip:alice%03d@127.0.0.1", i);
  407. snprintf(s_alice_tasks[i].to, sizeof(s_alice_tasks[i].to), "sip:bob%03d@127.0.0.1", i);
  408. thread_create(&alice[i], AliceThread, &s_alice_tasks[i]);
  409. s_bob_tasks[i].dialog = NULL;
  410. s_bob_tasks[i].self = &s_sip.bob;
  411. s_bob_tasks[i].peer = &s_sip.alice;
  412. s_bob_tasks[i].success = 0;
  413. s_bob_tasks[i].failed = 0;
  414. s_bob_tasks[i].terminated = 0;
  415. snprintf(s_bob_tasks[i].from, sizeof(s_bob_tasks[i].from), "sip:BOB%03d@127.0.0.1", i);
  416. snprintf(s_bob_tasks[i].to, sizeof(s_bob_tasks[i].to), "sip:ALICE%03d@127.0.0.1", i);
  417. thread_create(&bob[i], AliceThread, &s_bob_tasks[i]);
  418. }
  419. // do worker
  420. for (int i = 0; i < NCONCURRENT; i++)
  421. {
  422. thread_destroy(alice[i]);
  423. thread_destroy(bob[i]);
  424. }
  425. s_sip.running = false;
  426. for (int i = 0; i < NQUEUE; i++)
  427. {
  428. sip_packet_t pkt;
  429. memset(&pkt, 0, sizeof(pkt));
  430. pkt.ptr = CHANNEL_DONE;
  431. channel_push(s_sip.alice.q[i], &pkt);
  432. channel_push(s_sip.bob.q[i], &pkt);
  433. thread_destroy(worker[2 * i]);
  434. thread_destroy(worker[2 * i + 1]);
  435. }
  436. for (int i = 0; i < NQUEUE; i++)
  437. {
  438. assert(0 == channel_count(s_sip.alice.q[i]));
  439. assert(0 == channel_count(s_sip.bob.q[i]));
  440. channel_destroy(&s_sip.alice.q[i]);
  441. channel_destroy(&s_sip.bob.q[i]);
  442. }
  443. while(s_sip.alice.count != 0 || s_sip.bob.count != 0)
  444. system_sleep(10);
  445. assert(0 == sip_agent_destroy(s_sip.alice.sip));
  446. assert(0 == sip_agent_destroy(s_sip.bob.sip));
  447. socket_close(s_sip.udp);
  448. sip_timer_cleanup();
  449. }