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.

261 line
8.7KB

  1. #include <memory>
  2. #include "sockutil.h"
  3. #include "aio-timeout.h"
  4. #include "sip-uac.h"
  5. #include "sip-message.h"
  6. #include "sip-transport.h"
  7. #include "sip-timer.h"
  8. #include "port/ip-route.h"
  9. #include "http-parser.h"
  10. #include "http-header-auth.h"
  11. #include "sys/thread.h"
  12. #include "sys/system.h"
  13. #include "uri-parse.h"
  14. #include "cstringext.h"
  15. #include "base64.h"
  16. #include "md5.h"
  17. #include <stdint.h>
  18. struct sip_uac_test_t
  19. {
  20. socket_t udp;
  21. socklen_t addrlen;
  22. struct sockaddr_storage addr;
  23. http_parser_t* parser;
  24. struct sip_agent_t* sip;
  25. struct sip_transport_t transport;
  26. };
  27. static int sip_uac_transport_via(void* transport, const char* destination, char protocol[16], char local[128], char dns[128])
  28. {
  29. int r;
  30. char ip[65];
  31. u_short port;
  32. struct uri_t* uri;
  33. struct sip_uac_test_t *test = (struct sip_uac_test_t *)transport;
  34. // rfc3263 4.1 Selecting a Transport Protocol
  35. // 1. If the URI specifies a transport protocol in the transport parameter,
  36. // that transport protocol SHOULD be used. Otherwise, if no transport
  37. // protocol is specified, but the TARGET(maddr) is a numeric IP address,
  38. // the client SHOULD use UDP for a SIP URI, and TCP for a SIPS URI.
  39. // 2. if no transport protocol is specified, and the TARGET is not numeric,
  40. // but an explicit port is provided, the client SHOULD use UDP for a SIP URI,
  41. // and TCP for a SIPS URI
  42. // 3. Otherwise, if no transport protocol or port is specified, and the target
  43. // is not a numeric IP address, the client SHOULD perform a NAPTR query for
  44. // the domain in the URI.
  45. // The client SHOULD try the first record. If an attempt should fail, based on
  46. // the definition of failure in Section 4.3, the next SHOULD be tried, and if
  47. // that should fail, the next SHOULD be tried, and so on.
  48. test->addrlen = sizeof(test->addr);
  49. memset(&test->addr, 0, sizeof(test->addr));
  50. strcpy(protocol, "UDP");
  51. uri = uri_parse(destination, strlen(destination));
  52. if (!uri)
  53. return -1; // invalid uri
  54. // rfc3263 4-Client Usage (p5)
  55. // once a SIP server has successfully been contacted (success is defined below),
  56. // all retransmissions of the SIP request and the ACK for non-2xx SIP responses
  57. // to INVITE MUST be sent to the same host.
  58. // Furthermore, a CANCEL for a particular SIP request MUST be sent to the same
  59. // SIP server that the SIP request was delivered to.
  60. // TODO: sips port
  61. r = socket_addr_from(&test->addr, &test->addrlen, uri->host, uri->port ? uri->port : SIP_PORT);
  62. if (0 == r)
  63. {
  64. socket_addr_to((struct sockaddr*)&test->addr, test->addrlen, ip, &port);
  65. socket_getname(test->udp, local, &port);
  66. r = ip_route_get(ip, local);
  67. if (0 == r)
  68. {
  69. dns[0] = 0;
  70. struct sockaddr_storage ss;
  71. socklen_t len = sizeof(ss);
  72. if (0 == socket_addr_from(&ss, &len, local, port))
  73. socket_addr_name((struct sockaddr*)&ss, len, dns, 128);
  74. if (SIP_PORT != port)
  75. snprintf(local + strlen(local), 128 - strlen(local), ":%hu", port);
  76. if (NULL == strchr(dns, '.'))
  77. snprintf(dns, 128, "%s", local); // don't have valid dns
  78. }
  79. }
  80. uri_free(uri);
  81. return r;
  82. }
  83. static int sip_uac_transport_send(void* transport, const void* data, size_t bytes)
  84. {
  85. struct sip_uac_test_t *test = (struct sip_uac_test_t *)transport;
  86. //char p1[1024];
  87. //char p2[1024];
  88. ((char*)data)[bytes] = 0;
  89. printf("%s\n", (const char*)data);
  90. int r = socket_sendto(test->udp, data, bytes, 0, (struct sockaddr*)&test->addr, test->addrlen);
  91. return r == bytes ? 0 : -1;
  92. }
  93. static void sip_uac_recv_reply(struct sip_uac_test_t *test)
  94. {
  95. uint8_t buffer[2 * 1024];
  96. struct sockaddr_storage addr;
  97. socklen_t addrlen = sizeof(addr);
  98. do
  99. {
  100. int r = socket_recvfrom(test->udp, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &addrlen);
  101. size_t n = r;
  102. if (0 == http_parser_input(test->parser, buffer, &n))
  103. {
  104. struct sip_message_t* reply = sip_message_create(SIP_MESSAGE_REPLY);
  105. r = sip_message_load(reply, test->parser);
  106. assert(0 == sip_agent_input(test->sip, reply, NULL));
  107. sip_message_destroy(reply);
  108. http_parser_clear(test->parser);
  109. break;
  110. }
  111. } while (1);
  112. }
  113. static int sip_uac_onregister(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  114. {
  115. char buffer[1024];
  116. struct sip_uac_test_t *test = (struct sip_uac_test_t *)param;
  117. if (200 <= code && code < 300)
  118. {
  119. }
  120. else if (401 == code)
  121. {
  122. // https://blog.csdn.net/yunlianglinfeng/article/details/81109380
  123. // http://www.voidcn.com/article/p-oqqbqgvd-bgn.html
  124. const char* h;
  125. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_register(test->sip, "sip:34020000001320000001@192.168.154.1", "sip:192.168.154.128", 3600, sip_uac_onregister, param), sip_uac_transaction_release);
  126. h = http_get_header_by_name(test->parser, "Call-ID");
  127. sip_uac_add_header(t.get(), "Call-ID", h); // All registrations from a UAC SHOULD use the same Call-ID
  128. h = http_get_header_by_name(test->parser, "CSeq");
  129. snprintf(buffer, sizeof(buffer), "%u REGISTER", atoi(h) + 1);
  130. sip_uac_add_header(t.get(), "CSeq", buffer); // A UA MUST increment the CSeq value by one for each REGISTER request with the same Call-ID
  131. // Unauthorized
  132. struct http_header_www_authenticate_t auth;
  133. memset(&auth, 0, sizeof(auth));
  134. h = http_get_header_by_name(test->parser, "WWW-Authenticate");
  135. assert(0 == http_header_www_authenticate(h, &auth));
  136. switch (auth.scheme)
  137. {
  138. case HTTP_AUTHENTICATION_DIGEST:
  139. //HA1=md5(username:realm:password)
  140. //HA2=md5(Method:Uri)
  141. //RESPONSE=md5(HA1:nonce:HA2)
  142. ++auth.nc;
  143. if(!auth.algorithm[0])
  144. snprintf(auth.algorithm, sizeof(auth.algorithm), "MD5");
  145. if (!auth.qop[0])
  146. snprintf(auth.qop, sizeof(auth.qop), "auth");
  147. else if (strchr(auth.qop, ','))
  148. *strchr(auth.qop, ',') = '\0'; // replace auth,auth-int -> auth
  149. snprintf(auth.uri, sizeof(auth.uri), "sip:%s", "192.168.154.128");
  150. snprintf(auth.username, sizeof(auth.username), "%s", "34020000001320000001");
  151. http_header_auth(&auth, "12345678", "REGISTER", NULL, 0, buffer, sizeof(buffer));
  152. sip_uac_add_header(t.get(), "Authorization", buffer);
  153. assert(0 == sip_uac_send(t.get(), NULL, 0, &test->transport, test));
  154. sip_uac_recv_reply(test);
  155. break;
  156. case HTTP_AUTHENTICATION_BASIC:
  157. break;
  158. default:
  159. assert(0);
  160. }
  161. }
  162. else
  163. {
  164. }
  165. return 0;
  166. }
  167. static void sip_uac_register_test(struct sip_uac_test_t *test)
  168. {
  169. //t = sip_uac_register(uac, "Bob <sip:bob@biloxi.com>", "sip:registrar.biloxi.com", 7200, sip_uac_message_onregister, test);
  170. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_register(test->sip, "sip:34020000001320000001@192.168.154.1", "sip:192.168.154.128", 3600, sip_uac_onregister, test), sip_uac_transaction_release);
  171. assert(0 == sip_uac_send(t.get(), NULL, 0, &test->transport, test));
  172. sip_uac_recv_reply(test);
  173. }
  174. static int sip_uac_onmessage(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  175. {
  176. return 0;
  177. }
  178. static void sip_uac_message_test(struct sip_uac_test_t *test)
  179. {
  180. const char* msg = "<?xml version=\"1.0\"?>"
  181. "<Notify>"
  182. "<CmdType>Keepalive</CmdType>"
  183. "<SN>478</SN>"
  184. "<DeviceID>34020000001320000001</DeviceID>"
  185. "<Status>OK</Status>"
  186. "</Notify>";
  187. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_message(test->sip, "sip:34020000001320000001@192.168.154.1", "sip:34020000002000000001@192.168.154.128", sip_uac_onmessage, test), sip_uac_transaction_release);
  188. sip_uac_add_header(t.get(), "Content-Type", "Application/MANSCDP+xml");
  189. assert(0 == sip_uac_send(t.get(), msg, strlen(msg), &test->transport, test));
  190. sip_uac_recv_reply(test);
  191. }
  192. 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)
  193. {
  194. if (200 <= code && code < 300)
  195. {
  196. *session = NULL;
  197. sip_uac_ack(t, NULL, 0);
  198. }
  199. return NULL;
  200. }
  201. static void sip_uac_invite_test(struct sip_uac_test_t *test)
  202. {
  203. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_invite(test->sip, "sip:34020000001320000001@192.168.154.128", "sip:34020000001320000001@192.168.154.128", sip_uac_oninvited, test), sip_uac_transaction_release);
  204. assert(0 == sip_uac_send(t.get(), NULL, 0, &test->transport, test));
  205. sip_uac_recv_reply(test);
  206. }
  207. void sip_uac_test(void)
  208. {
  209. sip_timer_init();
  210. struct sip_uac_test_t test;
  211. test.transport = {
  212. sip_uac_transport_via,
  213. sip_uac_transport_send,
  214. };
  215. struct sip_uas_handler_t handler;
  216. memset(&handler, 0, sizeof(handler));
  217. test.udp = socket_udp();
  218. test.sip = sip_agent_create(&handler);
  219. test.parser = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
  220. socket_bind_any(test.udp, SIP_PORT);
  221. sip_uac_register_test(&test);
  222. sip_uac_message_test(&test);
  223. //sip_uac_invite_test(&test);
  224. sip_agent_destroy(test.sip);
  225. socket_close(test.udp);
  226. http_parser_destroy(test.parser);
  227. sip_timer_cleanup();
  228. }