lua-socket.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. #define LUA_LIB
  2. #include "skynet_malloc.h"
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdbool.h>
  6. #include <stdint.h>
  7. #include <assert.h>
  8. #include <lua.h>
  9. #include <lauxlib.h>
  10. #include <sys/types.h>
  11. #include <sys/socket.h>
  12. #include <arpa/inet.h>
  13. #include <netdb.h>
  14. #include <netinet/in.h>
  15. #include "skynet.h"
  16. #include "skynet_socket.h"
  17. #define BACKLOG 32
  18. // 2 ** 12 == 4096
  19. #define LARGE_PAGE_NODE 12
  20. #define POOL_SIZE_WARNING 32
  21. #define BUFFER_LIMIT (256 * 1024)
  22. struct buffer_node {
  23. char * msg;
  24. int sz;
  25. struct buffer_node *next;
  26. };
  27. struct socket_buffer {
  28. int size;
  29. int offset;
  30. struct buffer_node *head;
  31. struct buffer_node *tail;
  32. };
  33. static int
  34. lfreepool(lua_State *L) {
  35. struct buffer_node * pool = lua_touserdata(L, 1);
  36. int sz = lua_rawlen(L,1) / sizeof(*pool);
  37. int i;
  38. for (i=0;i<sz;i++) {
  39. struct buffer_node *node = &pool[i];
  40. if (node->msg) {
  41. skynet_free(node->msg);
  42. node->msg = NULL;
  43. }
  44. }
  45. return 0;
  46. }
  47. static int
  48. lnewpool(lua_State *L, int sz) {
  49. struct buffer_node * pool = lua_newuserdatauv(L, sizeof(struct buffer_node) * sz, 0);
  50. int i;
  51. for (i=0;i<sz;i++) {
  52. pool[i].msg = NULL;
  53. pool[i].sz = 0;
  54. pool[i].next = &pool[i+1];
  55. }
  56. pool[sz-1].next = NULL;
  57. if (luaL_newmetatable(L, "buffer_pool")) {
  58. lua_pushcfunction(L, lfreepool);
  59. lua_setfield(L, -2, "__gc");
  60. }
  61. lua_setmetatable(L, -2);
  62. return 1;
  63. }
  64. static int
  65. lnewbuffer(lua_State *L) {
  66. struct socket_buffer * sb = lua_newuserdatauv(L, sizeof(*sb), 0);
  67. sb->size = 0;
  68. sb->offset = 0;
  69. sb->head = NULL;
  70. sb->tail = NULL;
  71. return 1;
  72. }
  73. /*
  74. userdata send_buffer
  75. table pool
  76. lightuserdata msg
  77. int size
  78. return size
  79. Comment: The table pool record all the buffers chunk,
  80. and the first index [1] is a lightuserdata : free_node. We can always use this pointer for struct buffer_node .
  81. The following ([2] ...) userdatas in table pool is the buffer chunk (for struct buffer_node),
  82. we never free them until the VM closed. The size of first chunk ([2]) is 16 struct buffer_node,
  83. and the second size is 32 ... The largest size of chunk is LARGE_PAGE_NODE (4096)
  84. lpushbbuffer will get a free struct buffer_node from table pool, and then put the msg/size in it.
  85. lpopbuffer return the struct buffer_node back to table pool (By calling return_free_node).
  86. */
  87. static int
  88. lpushbuffer(lua_State *L) {
  89. struct socket_buffer *sb = lua_touserdata(L,1);
  90. if (sb == NULL) {
  91. return luaL_error(L, "need buffer object at param 1");
  92. }
  93. char * msg = lua_touserdata(L,3);
  94. if (msg == NULL) {
  95. return luaL_error(L, "need message block at param 3");
  96. }
  97. int pool_index = 2;
  98. luaL_checktype(L,pool_index,LUA_TTABLE);
  99. int sz = luaL_checkinteger(L,4);
  100. lua_rawgeti(L,pool_index,1);
  101. struct buffer_node * free_node = lua_touserdata(L,-1); // sb poolt msg size free_node
  102. lua_pop(L,1);
  103. if (free_node == NULL) {
  104. int tsz = lua_rawlen(L,pool_index);
  105. if (tsz == 0)
  106. tsz++;
  107. int size = 8;
  108. if (tsz <= LARGE_PAGE_NODE-3) {
  109. size <<= tsz;
  110. } else {
  111. size <<= LARGE_PAGE_NODE-3;
  112. }
  113. lnewpool(L, size);
  114. free_node = lua_touserdata(L,-1);
  115. lua_rawseti(L, pool_index, tsz+1);
  116. if (tsz > POOL_SIZE_WARNING) {
  117. skynet_error(NULL, "Too many socket pool (%d)", tsz);
  118. }
  119. }
  120. lua_pushlightuserdata(L, free_node->next);
  121. lua_rawseti(L, pool_index, 1); // sb poolt msg size
  122. free_node->msg = msg;
  123. free_node->sz = sz;
  124. free_node->next = NULL;
  125. if (sb->head == NULL) {
  126. assert(sb->tail == NULL);
  127. sb->head = sb->tail = free_node;
  128. } else {
  129. sb->tail->next = free_node;
  130. sb->tail = free_node;
  131. }
  132. sb->size += sz;
  133. lua_pushinteger(L, sb->size);
  134. return 1;
  135. }
  136. static void
  137. return_free_node(lua_State *L, int pool, struct socket_buffer *sb) {
  138. struct buffer_node *free_node = sb->head;
  139. sb->offset = 0;
  140. sb->head = free_node->next;
  141. if (sb->head == NULL) {
  142. sb->tail = NULL;
  143. }
  144. lua_rawgeti(L,pool,1);
  145. free_node->next = lua_touserdata(L,-1);
  146. lua_pop(L,1);
  147. skynet_free(free_node->msg);
  148. free_node->msg = NULL;
  149. free_node->sz = 0;
  150. lua_pushlightuserdata(L, free_node);
  151. lua_rawseti(L, pool, 1);
  152. }
  153. static void
  154. pop_lstring(lua_State *L, struct socket_buffer *sb, int sz, int skip) {
  155. struct buffer_node * current = sb->head;
  156. if (sz < current->sz - sb->offset) {
  157. lua_pushlstring(L, current->msg + sb->offset, sz-skip);
  158. sb->offset+=sz;
  159. return;
  160. }
  161. if (sz == current->sz - sb->offset) {
  162. lua_pushlstring(L, current->msg + sb->offset, sz-skip);
  163. return_free_node(L,2,sb);
  164. return;
  165. }
  166. luaL_Buffer b;
  167. luaL_buffinitsize(L, &b, sz);
  168. for (;;) {
  169. int bytes = current->sz - sb->offset;
  170. if (bytes >= sz) {
  171. if (sz > skip) {
  172. luaL_addlstring(&b, current->msg + sb->offset, sz - skip);
  173. }
  174. sb->offset += sz;
  175. if (bytes == sz) {
  176. return_free_node(L,2,sb);
  177. }
  178. break;
  179. }
  180. int real_sz = sz - skip;
  181. if (real_sz > 0) {
  182. luaL_addlstring(&b, current->msg + sb->offset, (real_sz < bytes) ? real_sz : bytes);
  183. }
  184. return_free_node(L,2,sb);
  185. sz-=bytes;
  186. if (sz==0)
  187. break;
  188. current = sb->head;
  189. assert(current);
  190. }
  191. luaL_pushresult(&b);
  192. }
  193. static int
  194. lheader(lua_State *L) {
  195. size_t len;
  196. const uint8_t * s = (const uint8_t *)luaL_checklstring(L, 1, &len);
  197. if (len > 4 || len < 1) {
  198. return luaL_error(L, "Invalid read %s", s);
  199. }
  200. int i;
  201. size_t sz = 0;
  202. for (i=0;i<(int)len;i++) {
  203. sz <<= 8;
  204. sz |= s[i];
  205. }
  206. lua_pushinteger(L, (lua_Integer)sz);
  207. return 1;
  208. }
  209. /*
  210. userdata send_buffer
  211. table pool
  212. integer sz
  213. */
  214. static int
  215. lpopbuffer(lua_State *L) {
  216. struct socket_buffer * sb = lua_touserdata(L, 1);
  217. if (sb == NULL) {
  218. return luaL_error(L, "Need buffer object at param 1");
  219. }
  220. luaL_checktype(L,2,LUA_TTABLE);
  221. int sz = luaL_checkinteger(L,3);
  222. if (sb->size < sz || sz == 0) {
  223. lua_pushnil(L);
  224. } else {
  225. pop_lstring(L,sb,sz,0);
  226. sb->size -= sz;
  227. }
  228. lua_pushinteger(L, sb->size);
  229. return 2;
  230. }
  231. /*
  232. userdata send_buffer
  233. table pool
  234. */
  235. static int
  236. lclearbuffer(lua_State *L) {
  237. struct socket_buffer * sb = lua_touserdata(L, 1);
  238. if (sb == NULL) {
  239. if (lua_isnil(L, 1)) {
  240. return 0;
  241. }
  242. return luaL_error(L, "Need buffer object at param 1");
  243. }
  244. luaL_checktype(L,2,LUA_TTABLE);
  245. while(sb->head) {
  246. return_free_node(L,2,sb);
  247. }
  248. sb->size = 0;
  249. return 0;
  250. }
  251. static int
  252. lreadall(lua_State *L) {
  253. struct socket_buffer * sb = lua_touserdata(L, 1);
  254. if (sb == NULL) {
  255. return luaL_error(L, "Need buffer object at param 1");
  256. }
  257. luaL_checktype(L,2,LUA_TTABLE);
  258. luaL_Buffer b;
  259. luaL_buffinit(L, &b);
  260. while(sb->head) {
  261. struct buffer_node *current = sb->head;
  262. luaL_addlstring(&b, current->msg + sb->offset, current->sz - sb->offset);
  263. return_free_node(L,2,sb);
  264. }
  265. luaL_pushresult(&b);
  266. sb->size = 0;
  267. return 1;
  268. }
  269. static int
  270. ldrop(lua_State *L) {
  271. void * msg = lua_touserdata(L,1);
  272. luaL_checkinteger(L,2);
  273. skynet_free(msg);
  274. return 0;
  275. }
  276. static bool
  277. check_sep(struct buffer_node * node, int from, const char *sep, int seplen) {
  278. for (;;) {
  279. int sz = node->sz - from;
  280. if (sz >= seplen) {
  281. return memcmp(node->msg+from,sep,seplen) == 0;
  282. }
  283. if (sz > 0) {
  284. if (memcmp(node->msg + from, sep, sz)) {
  285. return false;
  286. }
  287. }
  288. node = node->next;
  289. sep += sz;
  290. seplen -= sz;
  291. from = 0;
  292. }
  293. }
  294. /*
  295. userdata send_buffer
  296. table pool , nil for check
  297. string sep
  298. */
  299. static int
  300. lreadline(lua_State *L) {
  301. struct socket_buffer * sb = lua_touserdata(L, 1);
  302. if (sb == NULL) {
  303. return luaL_error(L, "Need buffer object at param 1");
  304. }
  305. // only check
  306. bool check = !lua_istable(L, 2);
  307. size_t seplen = 0;
  308. const char *sep = luaL_checklstring(L,3,&seplen);
  309. int i;
  310. struct buffer_node *current = sb->head;
  311. if (current == NULL)
  312. return 0;
  313. int from = sb->offset;
  314. int bytes = current->sz - from;
  315. for (i=0;i<=sb->size - (int)seplen;i++) {
  316. if (check_sep(current, from, sep, seplen)) {
  317. if (check) {
  318. lua_pushboolean(L,true);
  319. } else {
  320. pop_lstring(L, sb, i+seplen, seplen);
  321. sb->size -= i+seplen;
  322. }
  323. return 1;
  324. }
  325. ++from;
  326. --bytes;
  327. if (bytes == 0) {
  328. current = current->next;
  329. from = 0;
  330. if (current == NULL)
  331. break;
  332. bytes = current->sz;
  333. }
  334. }
  335. return 0;
  336. }
  337. static int
  338. lstr2p(lua_State *L) {
  339. size_t sz = 0;
  340. const char * str = luaL_checklstring(L,1,&sz);
  341. void *ptr = skynet_malloc(sz);
  342. memcpy(ptr, str, sz);
  343. lua_pushlightuserdata(L, ptr);
  344. lua_pushinteger(L, (int)sz);
  345. return 2;
  346. }
  347. // for skynet socket
  348. /*
  349. lightuserdata msg
  350. integer size
  351. return type n1 n2 ptr_or_string
  352. */
  353. static int
  354. lunpack(lua_State *L) {
  355. struct skynet_socket_message *message = lua_touserdata(L,1);
  356. int size = luaL_checkinteger(L,2);
  357. lua_pushinteger(L, message->type);
  358. lua_pushinteger(L, message->id);
  359. lua_pushinteger(L, message->ud);
  360. if (message->buffer == NULL) {
  361. lua_pushlstring(L, (char *)(message+1),size - sizeof(*message));
  362. } else {
  363. lua_pushlightuserdata(L, message->buffer);
  364. }
  365. if (message->type == SKYNET_SOCKET_TYPE_UDP) {
  366. int addrsz = 0;
  367. const char * addrstring = skynet_socket_udp_address(message, &addrsz);
  368. if (addrstring) {
  369. lua_pushlstring(L, addrstring, addrsz);
  370. return 5;
  371. }
  372. }
  373. return 4;
  374. }
  375. static const char *
  376. address_port(lua_State *L, char *tmp, const char * addr, int port_index, int *port) {
  377. const char * host;
  378. if (lua_isnoneornil(L,port_index)) {
  379. host = strchr(addr, '[');
  380. if (host) {
  381. // is ipv6
  382. ++host;
  383. const char * sep = strchr(addr,']');
  384. if (sep == NULL) {
  385. luaL_error(L, "Invalid address %s.",addr);
  386. }
  387. memcpy(tmp, host, sep-host);
  388. tmp[sep-host] = '\0';
  389. host = tmp;
  390. sep = strchr(sep + 1, ':');
  391. if (sep == NULL) {
  392. luaL_error(L, "Invalid address %s.",addr);
  393. }
  394. *port = strtoul(sep+1,NULL,10);
  395. } else {
  396. // is ipv4
  397. const char * sep = strchr(addr,':');
  398. if (sep == NULL) {
  399. luaL_error(L, "Invalid address %s.",addr);
  400. }
  401. memcpy(tmp, addr, sep-addr);
  402. tmp[sep-addr] = '\0';
  403. host = tmp;
  404. *port = strtoul(sep+1,NULL,10);
  405. }
  406. } else {
  407. host = addr;
  408. *port = luaL_optinteger(L,port_index, 0);
  409. }
  410. return host;
  411. }
  412. static int
  413. lconnect(lua_State *L) {
  414. size_t sz = 0;
  415. const char * addr = luaL_checklstring(L,1,&sz);
  416. char tmp[sz];
  417. int port = 0;
  418. const char * host = address_port(L, tmp, addr, 2, &port);
  419. if (port == 0) {
  420. return luaL_error(L, "Invalid port");
  421. }
  422. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  423. int id = skynet_socket_connect(ctx, host, port);
  424. lua_pushinteger(L, id);
  425. return 1;
  426. }
  427. static int
  428. lclose(lua_State *L) {
  429. int id = luaL_checkinteger(L,1);
  430. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  431. skynet_socket_close(ctx, id);
  432. return 0;
  433. }
  434. static int
  435. lshutdown(lua_State *L) {
  436. int id = luaL_checkinteger(L,1);
  437. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  438. skynet_socket_shutdown(ctx, id);
  439. return 0;
  440. }
  441. static int
  442. llisten(lua_State *L) {
  443. const char * host = luaL_checkstring(L,1);
  444. int port = luaL_checkinteger(L,2);
  445. int backlog = luaL_optinteger(L,3,BACKLOG);
  446. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  447. int id = skynet_socket_listen(ctx, host,port,backlog);
  448. if (id < 0) {
  449. return luaL_error(L, "Listen error");
  450. }
  451. lua_pushinteger(L,id);
  452. return 1;
  453. }
  454. static size_t
  455. count_size(lua_State *L, int index) {
  456. size_t tlen = 0;
  457. int i;
  458. for (i=1;lua_geti(L, index, i) != LUA_TNIL; ++i) {
  459. size_t len;
  460. luaL_checklstring(L, -1, &len);
  461. tlen += len;
  462. lua_pop(L,1);
  463. }
  464. lua_pop(L,1);
  465. return tlen;
  466. }
  467. static void
  468. concat_table(lua_State *L, int index, void *buffer, size_t tlen) {
  469. char *ptr = buffer;
  470. int i;
  471. for (i=1;lua_geti(L, index, i) != LUA_TNIL; ++i) {
  472. size_t len;
  473. const char * str = lua_tolstring(L, -1, &len);
  474. if (str == NULL || tlen < len) {
  475. break;
  476. }
  477. memcpy(ptr, str, len);
  478. ptr += len;
  479. tlen -= len;
  480. lua_pop(L,1);
  481. }
  482. if (tlen != 0) {
  483. skynet_free(buffer);
  484. luaL_error(L, "Invalid strings table");
  485. }
  486. lua_pop(L,1);
  487. }
  488. static void
  489. get_buffer(lua_State *L, int index, struct socket_sendbuffer *buf) {
  490. void *buffer;
  491. switch(lua_type(L, index)) {
  492. size_t len;
  493. case LUA_TUSERDATA:
  494. // lua full useobject must be a raw pointer, it can't be a socket object or a memory object.
  495. buf->type = SOCKET_BUFFER_RAWPOINTER;
  496. buf->buffer = lua_touserdata(L, index);
  497. if (lua_isinteger(L, index+1)) {
  498. buf->sz = lua_tointeger(L, index+1);
  499. } else {
  500. buf->sz = lua_rawlen(L, index);
  501. }
  502. break;
  503. case LUA_TLIGHTUSERDATA: {
  504. int sz = -1;
  505. if (lua_isinteger(L, index+1)) {
  506. sz = lua_tointeger(L,index+1);
  507. }
  508. if (sz < 0) {
  509. buf->type = SOCKET_BUFFER_OBJECT;
  510. } else {
  511. buf->type = SOCKET_BUFFER_MEMORY;
  512. }
  513. buf->buffer = lua_touserdata(L,index);
  514. buf->sz = (size_t)sz;
  515. break;
  516. }
  517. case LUA_TTABLE:
  518. // concat the table as a string
  519. len = count_size(L, index);
  520. buffer = skynet_malloc(len);
  521. concat_table(L, index, buffer, len);
  522. buf->type = SOCKET_BUFFER_MEMORY;
  523. buf->buffer = buffer;
  524. buf->sz = len;
  525. break;
  526. default:
  527. buf->type = SOCKET_BUFFER_RAWPOINTER;
  528. buf->buffer = luaL_checklstring(L, index, &buf->sz);
  529. break;
  530. }
  531. }
  532. static int
  533. lsend(lua_State *L) {
  534. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  535. int id = luaL_checkinteger(L, 1);
  536. struct socket_sendbuffer buf;
  537. buf.id = id;
  538. get_buffer(L, 2, &buf);
  539. int err = skynet_socket_sendbuffer(ctx, &buf);
  540. lua_pushboolean(L, !err);
  541. return 1;
  542. }
  543. static int
  544. lsendlow(lua_State *L) {
  545. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  546. int id = luaL_checkinteger(L, 1);
  547. struct socket_sendbuffer buf;
  548. buf.id = id;
  549. get_buffer(L, 2, &buf);
  550. int err = skynet_socket_sendbuffer_lowpriority(ctx, &buf);
  551. lua_pushboolean(L, !err);
  552. return 1;
  553. }
  554. static int
  555. lbind(lua_State *L) {
  556. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  557. int fd = luaL_checkinteger(L, 1);
  558. int id = skynet_socket_bind(ctx,fd);
  559. lua_pushinteger(L,id);
  560. return 1;
  561. }
  562. static int
  563. lstart(lua_State *L) {
  564. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  565. int id = luaL_checkinteger(L, 1);
  566. skynet_socket_start(ctx,id);
  567. return 0;
  568. }
  569. static int
  570. lpause(lua_State *L) {
  571. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  572. int id = luaL_checkinteger(L, 1);
  573. skynet_socket_pause(ctx,id);
  574. return 0;
  575. }
  576. static int
  577. lnodelay(lua_State *L) {
  578. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  579. int id = luaL_checkinteger(L, 1);
  580. skynet_socket_nodelay(ctx,id);
  581. return 0;
  582. }
  583. static int
  584. ludp(lua_State *L) {
  585. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  586. size_t sz = 0;
  587. const char * addr = lua_tolstring(L,1,&sz);
  588. char tmp[sz];
  589. int port = 0;
  590. const char * host = NULL;
  591. if (addr) {
  592. host = address_port(L, tmp, addr, 2, &port);
  593. }
  594. int id = skynet_socket_udp(ctx, host, port);
  595. if (id < 0) {
  596. return luaL_error(L, "udp init failed");
  597. }
  598. lua_pushinteger(L, id);
  599. return 1;
  600. }
  601. static int
  602. ludp_connect(lua_State *L) {
  603. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  604. int id = luaL_checkinteger(L, 1);
  605. size_t sz = 0;
  606. const char * addr = luaL_checklstring(L,2,&sz);
  607. char tmp[sz];
  608. int port = 0;
  609. const char * host = NULL;
  610. if (addr) {
  611. host = address_port(L, tmp, addr, 3, &port);
  612. }
  613. if (skynet_socket_udp_connect(ctx, id, host, port)) {
  614. return luaL_error(L, "udp connect failed");
  615. }
  616. return 0;
  617. }
  618. static int
  619. ludp_send(lua_State *L) {
  620. struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
  621. int id = luaL_checkinteger(L, 1);
  622. const char * address = luaL_checkstring(L, 2);
  623. struct socket_sendbuffer buf;
  624. buf.id = id;
  625. get_buffer(L, 3, &buf);
  626. int err = skynet_socket_udp_sendbuffer(ctx, address, &buf);
  627. lua_pushboolean(L, !err);
  628. return 1;
  629. }
  630. static int
  631. ludp_address(lua_State *L) {
  632. size_t sz = 0;
  633. const uint8_t * addr = (const uint8_t *)luaL_checklstring(L, 1, &sz);
  634. uint16_t port = 0;
  635. memcpy(&port, addr+1, sizeof(uint16_t));
  636. port = ntohs(port);
  637. const void * src = addr+3;
  638. char tmp[256];
  639. int family;
  640. if (sz == 1+2+4) {
  641. family = AF_INET;
  642. } else {
  643. if (sz != 1+2+16) {
  644. return luaL_error(L, "Invalid udp address");
  645. }
  646. family = AF_INET6;
  647. }
  648. if (inet_ntop(family, src, tmp, sizeof(tmp)) == NULL) {
  649. return luaL_error(L, "Invalid udp address");
  650. }
  651. lua_pushstring(L, tmp);
  652. lua_pushinteger(L, port);
  653. return 2;
  654. }
  655. static void
  656. getinfo(lua_State *L, struct socket_info *si) {
  657. lua_newtable(L);
  658. lua_pushinteger(L, si->id);
  659. lua_setfield(L, -2, "id");
  660. lua_pushinteger(L, si->opaque);
  661. lua_setfield(L, -2, "address");
  662. switch(si->type) {
  663. case SOCKET_INFO_LISTEN:
  664. lua_pushstring(L, "LISTEN");
  665. lua_setfield(L, -2, "type");
  666. lua_pushinteger(L, si->read);
  667. lua_setfield(L, -2, "accept");
  668. lua_pushinteger(L, si->rtime);
  669. lua_setfield(L, -2, "rtime");
  670. if (si->name[0]) {
  671. lua_pushstring(L, si->name);
  672. lua_setfield(L, -2, "sock");
  673. }
  674. return;
  675. case SOCKET_INFO_TCP:
  676. lua_pushstring(L, "TCP");
  677. break;
  678. case SOCKET_INFO_UDP:
  679. lua_pushstring(L, "UDP");
  680. break;
  681. case SOCKET_INFO_BIND:
  682. lua_pushstring(L, "BIND");
  683. break;
  684. case SOCKET_INFO_CLOSING:
  685. lua_pushstring(L, "CLOSING");
  686. break;
  687. default:
  688. lua_pushstring(L, "UNKNOWN");
  689. lua_setfield(L, -2, "type");
  690. return;
  691. }
  692. lua_setfield(L, -2, "type");
  693. lua_pushinteger(L, si->read);
  694. lua_setfield(L, -2, "read");
  695. lua_pushinteger(L, si->write);
  696. lua_setfield(L, -2, "write");
  697. lua_pushinteger(L, si->wbuffer);
  698. lua_setfield(L, -2, "wbuffer");
  699. lua_pushinteger(L, si->rtime);
  700. lua_setfield(L, -2, "rtime");
  701. lua_pushinteger(L, si->wtime);
  702. lua_setfield(L, -2, "wtime");
  703. lua_pushboolean(L, si->reading);
  704. lua_setfield(L, -2, "reading");
  705. lua_pushboolean(L, si->writing);
  706. lua_setfield(L, -2, "writing");
  707. if (si->name[0]) {
  708. lua_pushstring(L, si->name);
  709. lua_setfield(L, -2, "peer");
  710. }
  711. }
  712. static int
  713. linfo(lua_State *L) {
  714. lua_newtable(L);
  715. struct socket_info * si = skynet_socket_info();
  716. struct socket_info * temp = si;
  717. int n = 0;
  718. while (temp) {
  719. getinfo(L, temp);
  720. lua_seti(L, -2, ++n);
  721. temp = temp->next;
  722. }
  723. socket_info_release(si);
  724. return 1;
  725. }
  726. static int
  727. lresolve(lua_State *L) {
  728. const char * host = luaL_checkstring(L, 1);
  729. int status;
  730. struct addrinfo ai_hints;
  731. struct addrinfo *ai_list = NULL;
  732. struct addrinfo *ai_ptr = NULL;
  733. memset( &ai_hints, 0, sizeof( ai_hints ) );
  734. status = getaddrinfo( host, NULL, &ai_hints, &ai_list);
  735. if ( status != 0 ) {
  736. return luaL_error(L, gai_strerror(status));
  737. }
  738. lua_newtable(L);
  739. int idx = 1;
  740. char tmp[128];
  741. for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) {
  742. struct sockaddr * addr = ai_ptr->ai_addr;
  743. void * sin_addr = (ai_ptr->ai_family == AF_INET) ? (void*)&((struct sockaddr_in *)addr)->sin_addr : (void*)&((struct sockaddr_in6 *)addr)->sin6_addr;
  744. if (inet_ntop(ai_ptr->ai_family, sin_addr, tmp, sizeof(tmp))) {
  745. lua_pushstring(L, tmp);
  746. lua_rawseti(L, -2, idx++);
  747. }
  748. }
  749. freeaddrinfo(ai_list);
  750. return 1;
  751. }
  752. LUAMOD_API int
  753. luaopen_skynet_socketdriver(lua_State *L) {
  754. luaL_checkversion(L);
  755. luaL_Reg l[] = {
  756. { "buffer", lnewbuffer },
  757. { "push", lpushbuffer },
  758. { "pop", lpopbuffer },
  759. { "drop", ldrop },
  760. { "readall", lreadall },
  761. { "clear", lclearbuffer },
  762. { "readline", lreadline },
  763. { "str2p", lstr2p },
  764. { "header", lheader },
  765. { "info", linfo },
  766. { "unpack", lunpack },
  767. { NULL, NULL },
  768. };
  769. luaL_newlib(L,l);
  770. luaL_Reg l2[] = {
  771. { "connect", lconnect },
  772. { "close", lclose },
  773. { "shutdown", lshutdown },
  774. { "listen", llisten },
  775. { "send", lsend },
  776. { "lsend", lsendlow },
  777. { "bind", lbind },
  778. { "start", lstart },
  779. { "pause", lpause },
  780. { "nodelay", lnodelay },
  781. { "udp", ludp },
  782. { "udp_connect", ludp_connect },
  783. { "udp_send", ludp_send },
  784. { "udp_address", ludp_address },
  785. { "resolve", lresolve },
  786. { NULL, NULL },
  787. };
  788. lua_getfield(L, LUA_REGISTRYINDEX, "skynet_context");
  789. struct skynet_context *ctx = lua_touserdata(L,-1);
  790. if (ctx == NULL) {
  791. return luaL_error(L, "Init skynet context first");
  792. }
  793. luaL_setfuncs(L,l2,1);
  794. return 1;
  795. }