jnetlib.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. #include "jnetlib.h"
  2. #include "httpget.h"
  3. #include "sslconnection.h"
  4. #include "asyncdns.h"
  5. #include "util.h"
  6. #include "httpserv.h"
  7. #include "httpuserv.h"
  8. #include "listen.h"
  9. #include "multicastlisten.h"
  10. #include "foundation/error.h"
  11. #include <new>
  12. int jnl_init()
  13. {
  14. return JNL::open_socketlib();
  15. }
  16. void jnl_quit()
  17. {
  18. JNL::close_socketlib();
  19. }
  20. /* --- Connection --- */
  21. jnl_connection_t jnl_connection_create(jnl_dns_t dns, size_t sendbufsize, size_t recvbufsize)
  22. {
  23. JNL_Connection *connection = new (std::nothrow) JNL_Connection((JNL_AsyncDNS *)dns, sendbufsize, recvbufsize);
  24. return (jnl_connection_t)connection;
  25. }
  26. jnl_connection_t jnl_sslconnection_create(jnl_dns_t dns, size_t sendbufsize, size_t recvbufsize)
  27. {
  28. JNL_SSL_Connection *connection = new (std::nothrow) JNL_SSL_Connection(NULL, (JNL_AsyncDNS *)dns, sendbufsize, recvbufsize);
  29. return (jnl_connection_t)connection;
  30. }
  31. void jnl_connection_run(jnl_connection_t _connection, size_t max_send_bytes, size_t max_receive_bytes, size_t *bytes_sent, size_t *bytes_received)
  32. {
  33. JNL_Connection *connection = (JNL_Connection *)_connection;
  34. connection->run(max_send_bytes, max_receive_bytes, bytes_sent, bytes_received);
  35. }
  36. int jnl_connection_get_state(jnl_connection_t _connection)
  37. {
  38. JNL_Connection *connection = (JNL_Connection *)_connection;
  39. return connection->get_state();
  40. }
  41. size_t jnl_connection_send_bytes_available(jnl_connection_t _connection)
  42. {
  43. JNL_Connection *connection = (JNL_Connection *)_connection;
  44. return connection->send_bytes_available();
  45. }
  46. size_t jnl_connection_receive_bytes_available(jnl_connection_t _connection)
  47. {
  48. JNL_Connection *connection = (JNL_Connection *)_connection;
  49. return connection->recv_bytes_available();
  50. }
  51. int jnl_connection_send(jnl_connection_t _connection, const void *bytes, size_t size)
  52. {
  53. JNL_Connection *connection = (JNL_Connection *)_connection;
  54. return connection->send(bytes, size);
  55. }
  56. JNL_API int jnl_connection_send_string(jnl_connection_t _connection, const char *str)
  57. {
  58. JNL_Connection *connection = (JNL_Connection *)_connection;
  59. return connection->send_string(str);
  60. }
  61. size_t jnl_connection_send_bytes_in_queue(jnl_connection_t _connection)
  62. {
  63. JNL_Connection *connection = (JNL_Connection *)_connection;
  64. return connection->send_bytes_in_queue();
  65. }
  66. size_t jnl_connection_receive(jnl_connection_t _connection, void *bytes, size_t size)
  67. {
  68. JNL_Connection *connection = (JNL_Connection *)_connection;
  69. return connection->recv_bytes(bytes, size);
  70. }
  71. size_t jnl_connection_peek(jnl_connection_t _connection, void *bytes, size_t size)
  72. {
  73. JNL_Connection *connection = (JNL_Connection *)_connection;
  74. return connection->peek_bytes(bytes, size);
  75. }
  76. void jnl_connection_release(jnl_connection_t _connection)
  77. {
  78. JNL_Connection *connection = (JNL_Connection *)_connection;
  79. if (connection)
  80. connection->Release();
  81. }
  82. int jnl_connection_receive_line(jnl_connection_t _connection, void *bytes, size_t size)
  83. {
  84. JNL_Connection *connection = (JNL_Connection *)_connection;
  85. return connection->recv_line((char *)bytes, size);
  86. }
  87. size_t jnl_connection_receive_lines_available(jnl_connection_t _connection)
  88. {
  89. JNL_Connection *connection = (JNL_Connection *)_connection;
  90. return connection->recv_lines_available();
  91. }
  92. void jnl_connection_close(jnl_connection_t _connection, int fast)
  93. {
  94. JNL_Connection *connection = (JNL_Connection *)_connection;
  95. connection->close(fast);
  96. }
  97. void jnl_connection_connect(jnl_connection_t _connection, const char *hostname, int port)
  98. {
  99. JNL_Connection *connection = (JNL_Connection *)_connection;
  100. connection->connect(hostname, port);
  101. }
  102. const char *jnl_connection_get_error(jnl_connection_t _connection)
  103. {
  104. JNL_Connection *connection = (JNL_Connection *)_connection;
  105. return connection->get_errstr();
  106. }
  107. /* ---- UDP ----- */
  108. int jnl_udp_create_multicast_listener(jnl_udp_t *connection, const char *mcast_ip, unsigned short port)
  109. {
  110. JNL_UDPConnection *udp = 0;
  111. JNL::open_socketlib(); // TODO: cut
  112. int ret = CreateMulticastListener(&udp, mcast_ip, port);
  113. if (ret != NErr_Success)
  114. {
  115. JNL::close_socketlib(); // TODO: cut
  116. return ret;
  117. }
  118. *connection = (jnl_udp_t)udp;
  119. return NErr_Success;
  120. }
  121. void jnl_udp_release(jnl_udp_t _connection)
  122. {
  123. JNL_UDPConnection *connection = (JNL_UDPConnection *)_connection;
  124. delete connection; // TODO: reference count
  125. JNL::close_socketlib(); // TODO: cut
  126. }
  127. void jnl_udp_run(jnl_udp_t _connection, size_t max_send_bytes, size_t max_recv_bytes, size_t *bytes_sent, size_t *bytes_rcvd)
  128. {
  129. JNL_UDPConnection *connection = (JNL_UDPConnection *)_connection;
  130. if (connection)
  131. {
  132. connection->run(max_send_bytes, max_recv_bytes, bytes_sent, bytes_rcvd);
  133. }
  134. }
  135. size_t jnl_udp_recv_bytes(jnl_udp_t _connection, void *buf, size_t len)
  136. {
  137. JNL_UDPConnection *connection = (JNL_UDPConnection *)_connection;
  138. if (connection)
  139. {
  140. return connection->recv_bytes(buf, len);
  141. }
  142. else
  143. return 0;
  144. }
  145. int jnl_udp_send(jnl_udp_t _connection, const void *bytes, size_t size)
  146. {
  147. JNL_UDPConnection *connection = (JNL_UDPConnection *)_connection;
  148. return connection->send(bytes, size);
  149. }
  150. void jnl_udp_set_peer(jnl_udp_t _connection, const char *hostname, unsigned short port)
  151. {
  152. JNL_UDPConnection *connection = (JNL_UDPConnection *)_connection;
  153. connection->setpeer(hostname, port);
  154. }
  155. void jnl_udp_set_peer_address(jnl_udp_t _connection, sockaddr *addr, socklen_t length)
  156. {
  157. JNL_UDPConnection *connection = (JNL_UDPConnection *)_connection;
  158. connection->setpeer(addr, length);
  159. }
  160. int jnl_udp_get_address(jnl_udp_t _connection, sockaddr **addr, socklen_t *length)
  161. {
  162. JNL_UDPConnection *connection = (JNL_UDPConnection *)_connection;
  163. connection->get_last_recv_msg_addr(addr, length);
  164. return NErr_Success;
  165. }
  166. /* ---- HTTP ---- */
  167. jnl_http_t jnl_http_create(int recvbufsize, int sendbufsize)
  168. {
  169. JNL_HTTPGet *http = new (std::nothrow) JNL_HTTPGet(recvbufsize, sendbufsize);
  170. return (jnl_http_t)http;
  171. }
  172. int jnl_http_set_recv_buffer_size(jnl_http_t _http, size_t new_size)
  173. {
  174. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  175. return http->set_recv_buffer_size(new_size);
  176. }
  177. int jnl_http_run(jnl_http_t _http)
  178. {
  179. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  180. return http->run();
  181. }
  182. size_t jnl_http_get_bytes(jnl_http_t _http, void *buf, size_t len)
  183. {
  184. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  185. return http->get_bytes(static_cast<char *>(buf), len);
  186. }
  187. size_t jnl_http_peek_bytes(jnl_http_t _http, void *buf, size_t len)
  188. {
  189. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  190. return http->peek_bytes(static_cast<char *>(buf), len);
  191. }
  192. size_t jnl_http_bytes_available(jnl_http_t _http)
  193. {
  194. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  195. return http->bytes_available();
  196. }
  197. uint64_t jnl_http_content_length(jnl_http_t _http)
  198. {
  199. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  200. return http->content_length();
  201. }
  202. int jnl_http_get_status(jnl_http_t _http)
  203. {
  204. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  205. return http->get_status();
  206. }
  207. int jnl_http_getreplycode(jnl_http_t _http)
  208. {
  209. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  210. return http->getreplycode();
  211. }
  212. const char *jnl_http_getreply(jnl_http_t _http)
  213. {
  214. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  215. return http->getreply();
  216. }
  217. const char *jnl_http_getheader(jnl_http_t _http, const char *header)
  218. {
  219. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  220. return http->getheader(header);
  221. }
  222. const char *jnl_http_get_all_headers(jnl_http_t _http)
  223. {
  224. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  225. return http->getallheaders();
  226. }
  227. void jnl_http_addheader(jnl_http_t _http, const char *header)
  228. {
  229. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  230. http->addheader(header);
  231. }
  232. void jnl_http_addheadervalue(jnl_http_t _http, const char *header, const char *value)
  233. {
  234. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  235. http->addheadervalue(header, value);
  236. }
  237. void jnl_http_connect(jnl_http_t _http, const char *url, int http_version, const char *method)
  238. {
  239. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  240. http->connect(url, http_version, method);
  241. }
  242. void jnl_http_release(jnl_http_t _http)
  243. {
  244. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  245. if (http)
  246. http->Release();
  247. }
  248. jnl_http_t jnl_http_retain(jnl_http_t _http)
  249. {
  250. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  251. if (http)
  252. http->Retain();
  253. return _http;
  254. }
  255. const char *jnl_http_get_url(jnl_http_t _http)
  256. {
  257. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  258. return http->get_url();
  259. }
  260. void jnl_http_reset_headers(jnl_http_t _http)
  261. {
  262. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  263. http->reset_headers();
  264. }
  265. void jnl_http_set_persistent(jnl_http_t _http)
  266. {
  267. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  268. http->set_persistent();
  269. }
  270. void jnl_http_allow_compression(jnl_http_t _http)
  271. {
  272. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  273. http->AllowCompression();
  274. }
  275. void jnl_http_allow_accept_all_reply_codes(jnl_http_t _http)
  276. {
  277. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  278. http->set_accept_all_reply_codes();
  279. }
  280. jnl_connection_t jnl_http_get_connection(jnl_http_t _http)
  281. {
  282. JNL_HTTPGet *http = (JNL_HTTPGet *)_http;
  283. return (jnl_connection_t)http->get_con();
  284. }
  285. void jnl_http_set_proxy(const char *proxy)
  286. {
  287. JNL_HTTPGet::set_proxy(proxy);
  288. }
  289. /* ------- HTTP Request Parser ------- */
  290. int jnl_http_request_create(jnl_http_request_t *_http, jnl_connection_t _connection)
  291. {
  292. JNL_HTTPServ *http = new (std::nothrow) JNL_HTTPServ((JNL_Connection *)_connection);;
  293. if (!http)
  294. return NErr_OutOfMemory;
  295. *_http = (jnl_http_request_t) http;
  296. return NErr_Success;
  297. }
  298. void jnl_http_request_release(jnl_http_request_t _http)
  299. {
  300. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  301. if (http)
  302. http->Release();
  303. }
  304. int jnl_http_request_run(jnl_http_request_t _http)
  305. {
  306. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  307. return http->run();
  308. }
  309. int jnl_htt_request_get_keep_alive(jnl_http_request_t _http)
  310. {
  311. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  312. return http->get_keep_alive();
  313. }
  314. const char *jnl_http_request_get_header(jnl_http_request_t _http, const char *header)
  315. {
  316. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  317. return http->getheader(header);
  318. }
  319. void jnl_http_request_reset(jnl_http_request_t _http)
  320. {
  321. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  322. http->reset();
  323. }
  324. void jnl_http_request_addheader(jnl_http_request_t _http, const char *header)
  325. {
  326. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  327. http->add_reply_header(header);
  328. }
  329. void jnl_http_request_set_reply_string(jnl_http_request_t _http, const char *reply)
  330. {
  331. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  332. http->set_reply_string(reply);
  333. }
  334. void jnl_http_request_send_reply(jnl_http_request_t _http)
  335. {
  336. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  337. http->send_reply();
  338. }
  339. const char *jnl_http_request_get_uri(jnl_http_request_t _http)
  340. {
  341. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  342. return http->get_request_file();
  343. }
  344. const char *jnl_http_request_get_parameter(jnl_http_request_t _http, const char *parameter)
  345. {
  346. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  347. return http->get_request_parm(parameter);
  348. }
  349. jnl_connection_t jnl_http_request_get_connection(jnl_http_request_t _http)
  350. {
  351. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  352. JNL_Connection *connection = http->get_con();
  353. if (connection)
  354. {
  355. connection->Retain();
  356. return (jnl_connection_t)connection;
  357. }
  358. else
  359. return 0;
  360. }
  361. const char *jnl_http_request_get_method(jnl_http_request_t _http)
  362. {
  363. JNL_HTTPServ *http = (JNL_HTTPServ *)_http;
  364. return http->get_method();
  365. }
  366. /* ------- HTTPU Request Parser ------- */
  367. int jnl_httpu_request_create(jnl_httpu_request_t *_httpu)
  368. {
  369. JNL_HTTPUServ *httpu = new (std::nothrow) JNL_HTTPUServ;
  370. if (!httpu)
  371. return NErr_OutOfMemory;
  372. *_httpu = (jnl_httpu_request_t) httpu;
  373. return NErr_Success;
  374. }
  375. void jnl_httpu_request_release(jnl_httpu_request_t _httpu)
  376. {
  377. JNL_HTTPUServ *httpu = (JNL_HTTPUServ *)_httpu;
  378. delete httpu; // TODO: reference count
  379. }
  380. int jnl_httpu_request_process(jnl_httpu_request_t _httpu, jnl_udp_t _udp)
  381. {
  382. JNL_HTTPUServ *httpu = (JNL_HTTPUServ *)_httpu;
  383. return httpu->process((JNL_UDPConnection *)_udp);
  384. }
  385. const char *jnl_httpu_request_get_method(jnl_httpu_request_t _httpu)
  386. {
  387. JNL_HTTPUServ *httpu = (JNL_HTTPUServ *)_httpu;
  388. return httpu->get_method();
  389. }
  390. const char *jnl_httpu_request_get_uri(jnl_httpu_request_t _httpu)
  391. {
  392. JNL_HTTPUServ *httpu = (JNL_HTTPUServ *)_httpu;
  393. return httpu->get_request_uri();
  394. }
  395. const char *jnl_httpu_request_get_header(jnl_httpu_request_t _httpu, const char *header)
  396. {
  397. JNL_HTTPUServ *httpu = (JNL_HTTPUServ *)_httpu;
  398. return httpu->getheader(header);
  399. }
  400. /* ----- DNS ----- */
  401. int jnl_dns_create(jnl_dns_t *out_dns)
  402. {
  403. JNL_AsyncDNS *dns = new (std::nothrow)JNL_AsyncDNS;
  404. if (!dns)
  405. return NErr_OutOfMemory;
  406. *out_dns = (jnl_dns_t)dns;
  407. return NErr_Success;
  408. }
  409. void jnl_dns_release(jnl_dns_t _dns)
  410. {
  411. JNL_AsyncDNS *dns = (JNL_AsyncDNS *)_dns;
  412. delete dns; // TODO: reference counting
  413. }
  414. int jnl_dns_resolve(jnl_dns_t _dns, const char *hostname, unsigned short port, addrinfo **addr, int sockettype)
  415. {
  416. JNL_AsyncDNS *dns = (JNL_AsyncDNS *)_dns;
  417. int ret = dns->resolve(hostname, port, addr, sockettype);
  418. if (ret == 0)
  419. return NErr_Success;
  420. else if (ret == -1)
  421. return NErr_TryAgain;
  422. else
  423. return NErr_Unknown;
  424. }
  425. int jnl_dns_resolve_now(const char *hostname, unsigned short port, addrinfo **addr, int sockettype)
  426. {
  427. int ret = JNL_AsyncDNS::resolvenow(hostname, port, addr, sockettype);
  428. if (ret == 0)
  429. return NErr_Success;
  430. else
  431. return NErr_Unknown;
  432. }
  433. void jnl_dns_freeaddrinfo(addrinfo *addr)
  434. {
  435. freeaddrinfo(addr);
  436. }
  437. void jnl_dns_gethostname(char *name, size_t cch)
  438. {
  439. gethostname(name, (int)cch);
  440. }
  441. #ifdef _WIN32
  442. PCSTR WSAAPI inet_ntop_xp(INT af, PVOID src, PSTR dst, size_t cnt)
  443. {
  444. struct sockaddr_in srcaddr;
  445. memset(&srcaddr, 0, sizeof(struct sockaddr_in));
  446. memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
  447. srcaddr.sin_family = af;
  448. if (WSAAddressToStringA((struct sockaddr*) &srcaddr, sizeof(struct sockaddr_in), 0, dst, (LPDWORD) &cnt) != 0) {
  449. return NULL;
  450. }
  451. return dst;
  452. }
  453. PCSTR WSAAPI inet_ntop_win32(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize) {
  454. typedef PCSTR (WSAAPI * win32_inet_ntop)(INT, PVOID, PSTR, size_t);
  455. static win32_inet_ntop pwin32_inet_ntop = NULL;
  456. if (!pwin32_inet_ntop){
  457. HMODULE hlib = LoadLibrary(L"WS2_32.DLL");
  458. pwin32_inet_ntop = (win32_inet_ntop)GetProcAddress(hlib, "inet_ntop");
  459. if (!pwin32_inet_ntop) {
  460. pwin32_inet_ntop = inet_ntop_xp;
  461. }
  462. }
  463. return (*pwin32_inet_ntop)(Family, pAddr, pStringBuf, StringBufSize);
  464. }
  465. #endif
  466. void jnl_dns_ntop(int af, const void *src, char *dst, socklen_t size)
  467. {
  468. #ifdef _WIN32
  469. // TODO need to revist this at a later date
  470. // [22:01:08] audiodsp: i will make a tweak for IPv6 compatability at some point
  471. // [22:01:49] audiodsp: just change references from sockaddr_in to sockaddr_storage
  472. // [22:02:24] audiodsp: keep it as is
  473. // [22:02:32] audiodsp: we're only using it in IPv4 mode at the moment
  474. // [22:02:40] audiodsp: i will fix when we need IPv6 server support
  475. // [22:03:58] audiodsp: the memcpy is what makes it non-trivial
  476. // [22:04:05] audiodsp: i have to switch on family and do different memcpy's accordingly
  477. // [22:04:16] audiodsp: or change the method to require a length
  478. // [22:04:19] audiodsp: which makes more sense
  479. // [22:04:29] audiodsp: and just not pass it to the linux function
  480. // [22:05:08] audiodsp: anyway not important.
  481. inet_ntop_win32(af, (PVOID)src, dst, size);
  482. #else
  483. inet_ntop(af, src, dst, size);
  484. #endif
  485. }
  486. /* Listen */
  487. int jnl_listen_create(jnl_listen_t *_listen, unsigned short port)
  488. {
  489. JNL_Listen *l = new (std::nothrow) JNL_Listen();
  490. if (!l)
  491. return NErr_OutOfMemory;
  492. int ret = l->Initialize(port);
  493. if (ret != NErr_Success)
  494. {
  495. delete l;
  496. return ret;
  497. }
  498. *_listen = (jnl_listen_t)l;
  499. return NErr_Success;
  500. }
  501. int jnl_listen_create_from_address(jnl_listen_t *_listen, struct addrinfo *addr, size_t index)
  502. {
  503. JNL_Listen *l = new (std::nothrow) JNL_Listen();
  504. if (!l)
  505. return NErr_OutOfMemory;
  506. int ret = l->Initialize(addr, index);
  507. if (ret != NErr_Success)
  508. {
  509. delete l;
  510. return ret;
  511. }
  512. *_listen = (jnl_listen_t)l;
  513. return NErr_Success;
  514. }
  515. jnl_connection_t jnl_listen_get_connection(jnl_listen_t _listen)
  516. {
  517. JNL_Listen *listen = (JNL_Listen *)_listen;
  518. JNL_Connection *connection = listen->get_connect();
  519. return (jnl_connection_t)connection;
  520. }
  521. unsigned short jnl_listen_get_port(jnl_listen_t _listen)
  522. {
  523. JNL_Listen *listen = (JNL_Listen *)_listen;
  524. return listen->get_port();
  525. }
  526. void jnl_listen_release(jnl_listen_t _listen)
  527. {
  528. JNL_Listen *listen = (JNL_Listen *)_listen;
  529. if (listen)
  530. listen->Release();
  531. }