PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/Socket/source/IoSocket.c

https://github.com/iamaleksey/io
C | 597 lines | 401 code | 104 blank | 92 comment | 38 complexity | 6813ecf8cb6b02d6c4847f2958a0edc8 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. //metadoc Socket copyright Steve Dekorte, 2004
  2. //metadoc Socket license BSD revised
  3. /*metadoc Socket description
  4. Interface to network communication.
  5. Sockets will auto yield to other coroutines while waiting on a request.
  6. All blocking operations use the timeout settings of the socket.
  7. Reads are appended to the socket's read buffer which can
  8. be accessed using the readBuffer method.
  9. Example:
  10. <pre>
  11. socket := Socket clone setHost("www.yahoo.com") setPort(80) connect
  12. if(socket error) then( write(socket error, "\n"); exit)
  13. socket write("GET /\n\n")
  14. while(socket read, Nop)
  15. if(socket error) then(write(socket error, "\n"); exit)
  16. write("read ", socket readBuffer length, " bytes\n")
  17. </pre>
  18. */
  19. //metadoc Socket category Networking
  20. /*doc Socket setHost(hostName)
  21. Translates hostName to an IP using asynchronous DNS and sets
  22. the host attribute. Returns self.
  23. */
  24. #include "IoSocket.h"
  25. #include "IoIPAddress.h"
  26. #include "IoState.h"
  27. #include "IoNumber.h"
  28. #include "IoSeq.h"
  29. #include "UArray.h"
  30. #include "List.h"
  31. IoSocket *IoMessage_locals_socketArgAt_(IoMessage *self, IoObject *locals, int n)
  32. {
  33. IoObject *v = IoMessage_locals_valueArgAt_(self, locals, n);
  34. if (!ISSOCKET(v))
  35. {
  36. IoMessage_locals_numberArgAt_errorForType_(self, locals, n, "Socket");
  37. }
  38. return v;
  39. }
  40. #define SOCKET(self) ((Socket *)IoObject_dataPointer(self))
  41. void IoSocket_tagCleanup(IoTag *self)
  42. {
  43. Socket_GlobalCleanup();
  44. }
  45. IoTag *IoSocket_newTag(void *state)
  46. {
  47. IoTag *tag = IoTag_newWithName_("Socket");
  48. IoTag_state_(tag, state);
  49. IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoSocket_free);
  50. IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoSocket_rawClone);
  51. IoTag_cleanupFunc_(tag, (IoTagCleanupFunc *)IoSocket_tagCleanup);
  52. Socket_GlobalInit();
  53. return tag;
  54. }
  55. IoSocket *IoSocket_proto(void *state)
  56. {
  57. IoObject *self = IoObject_new(state);
  58. IoObject_tag_(self, IoSocket_newTag(state));
  59. IoObject_setDataPointer_(self, Socket_new());
  60. IoState_registerProtoWithFunc_((IoState *)state, self, IoSocket_proto);
  61. {
  62. IoMethodTable methodTable[] = {
  63. {"asyncStreamOpen", IoSocket_asyncStreamOpen},
  64. {"asyncUdpOpen", IoSocket_asyncUdpOpen},
  65. {"isOpen", IoSocket_isOpen},
  66. {"isValid", IoSocket_isValid},
  67. {"isStream", IoSocket_isStream},
  68. {"asyncBind", IoSocket_asyncBind},
  69. {"asyncListen", IoSocket_asyncListen},
  70. {"asyncAccept", IoSocket_asyncAccept},
  71. {"asyncConnect", IoSocket_asyncConnect},
  72. {"asyncStreamRead", IoSocket_asyncStreamRead},
  73. {"asyncStreamWrite", IoSocket_asyncStreamWrite},
  74. {"asyncUdpRead", IoSocket_asyncUdpRead},
  75. {"asyncUdpWrite", IoSocket_asyncUdpWrite},
  76. {"close", IoSocket_close},
  77. {"descriptorId", IoSocket_descriptorId},
  78. {"setSocketReadBufferSize", IoSocket_setSocketReadBufferSize},
  79. {"setSocketWriteBufferSize", IoSocket_setSocketWriteBufferSize},
  80. {"getSocketReadLowWaterMark", IoSocket_getSocketReadLowWaterMark},
  81. {"getSocketWriteLowWaterMark", IoSocket_getSocketWriteLowWaterMark},
  82. {"setSocketReadLowWaterMark", IoSocket_setSocketReadLowWaterMark},
  83. {"setSocketWriteLowWaterMark", IoSocket_setSocketWriteLowWaterMark},
  84. {"setNoDelay", IoSocket_setNoDelay},
  85. {"errorNumber", IoSocket_errorNumber},
  86. {"errorDescription", IoSocket_errorDescription},
  87. {NULL, NULL}
  88. };
  89. IoObject_addMethodTable_(self, methodTable);
  90. }
  91. return self;
  92. }
  93. IoSocket *IoSocket_rawClone(IoSocket *proto)
  94. {
  95. IoObject *self = IoObject_rawClonePrimitive(proto);
  96. IoObject_setDataPointer_(self, Socket_new());
  97. return self;
  98. }
  99. IoSocket *IoSocket_new(void *state)
  100. {
  101. IoObject *proto = IoState_protoWithInitFunction_((IoState *)state, IoSocket_proto);
  102. return IOCLONE(proto);
  103. }
  104. // -----------------------------------------------------------
  105. IoSocket *IoSocket_newWithSocket_(void *state, Socket *socket)
  106. {
  107. IoSocket *self = IoSocket_new(state);
  108. Socket_free(SOCKET(self));
  109. IoObject_setDataPointer_(self, socket);
  110. return self;
  111. }
  112. void IoSocket_free(IoSocket *self)
  113. {
  114. Socket_free(SOCKET(self));
  115. }
  116. // ----------------------------------------
  117. IoSocket *IoSocket_rawSetupEvent_(IoSocket *self, IoObject *locals, IoMessage *m, char *eventSlotName)
  118. {
  119. IoObject *event = IoObject_rawGetSlot_(self, IOSYMBOL(eventSlotName));
  120. if(!event || ISNIL(event))
  121. {
  122. IoState_error_(IOSTATE, m, "Expected %s slot to be set!", eventSlotName);
  123. return IONIL(self);
  124. }
  125. else
  126. {
  127. IoObject_setSlot_to_(event, IOSYMBOL("descriptorId"), IoSocket_descriptorId(self, locals, m));
  128. return self;
  129. }
  130. }
  131. IoSocket *IoSocket_rawSetupEvents(IoSocket *self, IoObject *locals, IoMessage *m)
  132. {
  133. IoSocket_rawSetupEvent_(self, locals, m, "readEvent");
  134. IoSocket_rawSetupEvent_(self, locals, m, "writeEvent");
  135. return self;
  136. }
  137. IoObject *IoSocket_descriptorId(IoSocket *self, IoObject *locals, IoMessage *m)
  138. {
  139. //doc Socket descriptorId Returns the socket's file descriptor id as a Number.
  140. return IONUMBER((int) Socket_descriptor(SOCKET(self)));
  141. }
  142. SOCKET_DESCRIPTOR IoSocket_rawDescriptor(IoSocket *self)
  143. {
  144. return Socket_descriptor(SOCKET(self));
  145. }
  146. // ----------------------------------------
  147. IoObject *IoSocket_isStream(IoSocket *self, IoObject *locals, IoMessage *m)
  148. {
  149. //doc Socket isStream Returns true if the socket is a stream, false otherwise.
  150. return IOBOOL(self, Socket_isStream(SOCKET(self)));
  151. }
  152. IoObject *IoSocket_isOpen(IoSocket *self, IoObject *locals, IoMessage *m)
  153. {
  154. //doc Socket isOpen Returns true if the socket is open, false otherwise.
  155. return IOBOOL(self, Socket_isOpen(SOCKET(self)));
  156. }
  157. IoObject *IoSocket_isValid(IoSocket *self, IoObject *locals, IoMessage *m)
  158. {
  159. //doc Socket isValid Returns true if the socket is in valid state, closes the socket and returns false otherwise.
  160. int isValid = Socket_isValid(SOCKET(self));
  161. if (!isValid)
  162. IoSocket_close(self, locals, m);
  163. return IOBOOL(self, isValid);
  164. }
  165. // ----------------------------------------
  166. IoObject *IoSocket_asyncStreamOpen(IoSocket *self, IoObject *locals, IoMessage *m)
  167. {
  168. //doc Socket asyncStreamOpen Submits an async request to open the socket in stream mode and returns self immediately or an Error object on error.
  169. Socket *socket = SOCKET(self);
  170. SocketResetErrorStatus();
  171. if (Socket_streamOpen(socket) && Socket_isOpen(socket) && Socket_makeReusable(socket) && Socket_makeAsync(socket))
  172. {
  173. IoSocket_rawSetupEvents(self, locals, m);
  174. return self;
  175. }
  176. else
  177. {
  178. return SOCKETERROR("Failed to create stream socket");
  179. }
  180. }
  181. IoObject *IoSocket_asyncUdpOpen(IoSocket *self, IoObject *locals, IoMessage *m)
  182. {
  183. //doc Socket asyncUdpOpen Submits an async request to open the socket in UDP mode and returns self immediately or an Error object on error.
  184. Socket *socket = SOCKET(self);
  185. if (Socket_udpOpen(socket) && Socket_isOpen(socket) && Socket_makeReusable(socket) && Socket_makeAsync(socket))
  186. {
  187. IoSocket_rawSetupEvents(self, locals, m);
  188. return self;
  189. }
  190. else
  191. {
  192. return SOCKETERROR("Failed to create udp socket");
  193. }
  194. }
  195. // ----------------------------------------
  196. IoObject *IoSocket_asyncConnect(IoSocket *self, IoObject *locals, IoMessage *m)
  197. {
  198. //doc Socket asyncConnect(ipAddressObject) Connects ti the given IPAddress and returns self or an Error object on error.
  199. IPAddress *address = IoMessage_locals_rawIPAddressArgAt_(m, locals, 0);
  200. if (Socket_connectTo(SOCKET(self), address))
  201. {
  202. return self;
  203. }
  204. else
  205. {
  206. if (Socket_connectToFailed())
  207. {
  208. return SOCKETERROR("Socket connect failed");
  209. }
  210. else
  211. {
  212. return IONIL(self);
  213. }
  214. }
  215. }
  216. IoObject *IoSocket_close(IoSocket *self, IoObject *locals, IoMessage *m)
  217. {
  218. //doc Socket close Closes the socket and returns self. Returns nil on error.
  219. if (Socket_close(SOCKET(self)))
  220. {
  221. IoSocket_rawSetupEvents(self, locals, m);
  222. return self;
  223. }
  224. else
  225. {
  226. if (Socket_closeFailed())
  227. {
  228. return SOCKETERROR("Failed to close socket");
  229. }
  230. else
  231. {
  232. return IONIL(self);
  233. }
  234. }
  235. }
  236. // server -------------------------------
  237. IoObject *IoSocket_asyncBind(IoSocket *self, IoObject *locals, IoMessage *m)
  238. {
  239. //doc Socket asyncBind Binds the socket and returns self immediately or an Error object on error.
  240. IPAddress *address = IoMessage_locals_rawIPAddressArgAt_(m, locals, 0);
  241. if (Socket_bind(SOCKET(self), address))
  242. {
  243. return self;
  244. }
  245. else
  246. {
  247. return SOCKETERROR("Failed to bind socket");
  248. }
  249. }
  250. IoObject *IoSocket_asyncListen(IoSocket *self, IoObject *locals, IoMessage *m)
  251. {
  252. //doc Socket asyncListen Listens to the socket and returns self immediately or an Error object on error.
  253. if (Socket_listen(SOCKET(self)))
  254. {
  255. return self;
  256. }
  257. else
  258. {
  259. return SOCKETERROR("Socket listen failed");
  260. }
  261. }
  262. IoObject *IoSocket_asyncAccept(IoSocket *self, IoObject *locals, IoMessage *m)
  263. {
  264. //doc Socket asyncAccept(ipAddressObject) Immediately returns a socket for an connection if one is available or nil otherwise. Returns an Error object on error.
  265. IPAddress *address = IoMessage_locals_rawIPAddressArgAt_(m, locals, 0);
  266. Socket *socket = Socket_accept(SOCKET(self), address);
  267. if (socket)
  268. {
  269. IoObject *newSocket = IoSocket_newWithSocket_(IOSTATE, socket);
  270. newSocket = IoObject_initClone_(self, locals, m, newSocket);
  271. return IoSocket_rawSetupEvents(newSocket, locals, m);
  272. }
  273. else
  274. {
  275. if (Socket_asyncFailed())
  276. {
  277. return SOCKETERROR("Socket accept failed");
  278. }
  279. else
  280. {
  281. return IONIL(self);
  282. }
  283. }
  284. }
  285. // stream -------------------------------
  286. IoObject *IoSocket_asyncStreamRead(IoSocket *self, IoObject *locals, IoMessage *m)
  287. {
  288. /*doc Socket asyncStreamRead(aSeq, readSize)
  289. Reads up to readSize number of bytes into aSeq if data is available.
  290. Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected.
  291. */
  292. IoSeq *bufferSeq = IoMessage_locals_mutableSeqArgAt_(m, locals, 0);
  293. UArray *buffer = IoSeq_rawUArray(bufferSeq);
  294. size_t readSize = IoMessage_locals_intArgAt_(m, locals, 1);
  295. if (Socket_streamRead(SOCKET(self), buffer, readSize))
  296. {
  297. return self;
  298. }
  299. if (Socket_asyncFailed())
  300. {
  301. IoSocket_close(self, locals, m);
  302. return SOCKETERROR("Socket stream read failed");
  303. }
  304. //if (readSize == 0) //SocketErrorStatus() == 0)
  305. if (SocketErrorStatus() == 0)
  306. {
  307. // 0 bytes means the other end disconnected
  308. //printf("SocketErrorStatus() == 0, closing\n");
  309. IoSocket_close(self, locals, m);
  310. }
  311. return IONIL(self);
  312. }
  313. IoObject *IoSocket_asyncStreamWrite(IoSocket *self, IoObject *locals, IoMessage *m)
  314. {
  315. /*doc Socket asyncStreamWrite(aSeq, start, writeSize)
  316. Writes the slice of aSeq from start to start + writeSize to the socket.
  317. Returns self immediately if successful, otherwise closes the socket.
  318. Returns an error object on Error.
  319. Returns nil if the socket is disconnected.
  320. */
  321. IoSeq *bufferSeq = IoMessage_locals_seqArgAt_(m, locals, 0);
  322. UArray *buffer = IoSeq_rawUArray(bufferSeq);
  323. size_t start = IoMessage_locals_intArgAt_(m, locals, 1);
  324. size_t writeSize = IoMessage_locals_intArgAt_(m, locals, 2);
  325. size_t bytesWritten = Socket_streamWrite(SOCKET(self), buffer, start, writeSize);
  326. if (bytesWritten)
  327. {
  328. UArray_removeRange(buffer, start, bytesWritten);
  329. return self;
  330. }
  331. else
  332. {
  333. if (Socket_asyncFailed())
  334. {
  335. IoSocket_close(self, locals, m);
  336. return SOCKETERROR("Socket stream write failed");
  337. }
  338. else
  339. {
  340. int errorNumber = SocketErrorStatus();
  341. if (errorNumber == ECONNRESET) IoSocket_close(self, locals, m);
  342. return IONIL(self);
  343. }
  344. }
  345. }
  346. // udp ------------------------------
  347. IoObject *IoSocket_asyncUdpRead(IoSocket *self, IoObject *locals, IoMessage *m)
  348. {
  349. /*doc Socket asyncUdpRead(ipAddress, aSeq, readSize)
  350. Reads up to readSize number of bytes from ipAddress into aSeq if data is available.
  351. Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected.
  352. */
  353. IPAddress *address = IoMessage_locals_rawIPAddressArgAt_(m, locals, 0);
  354. UArray *buffer = IoSeq_rawUArray(IoMessage_locals_mutableSeqArgAt_(m, locals, 1));
  355. size_t readSize = IoMessage_locals_sizetArgAt_(m, locals, 2);
  356. if (Socket_udpRead(SOCKET(self), address, buffer, readSize))
  357. {
  358. return self;
  359. }
  360. else
  361. {
  362. if (Socket_asyncFailed())
  363. {
  364. return SOCKETERROR("Socket udp read failed");
  365. }
  366. else
  367. {
  368. return IONIL(self);
  369. }
  370. }
  371. }
  372. IoObject *IoSocket_asyncUdpWrite(IoSocket *self, IoObject *locals, IoMessage *m)
  373. {
  374. /*doc Socket asyncUdpWrite(ipAddress, aSeq, startIndex, readSize)
  375. Writes readsize bytes from aSeq starting at startIndex to ipAddress.
  376. Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected.
  377. */
  378. IPAddress *address = IoMessage_locals_rawIPAddressArgAt_(m, locals, 0);
  379. UArray *buffer = IoSeq_rawUArray(IoMessage_locals_seqArgAt_(m, locals, 1));
  380. size_t start = IoMessage_locals_intArgAt_(m, locals, 2);
  381. size_t writeSize = IoMessage_locals_intArgAt_(m, locals, 3);
  382. size_t bytesWritten = Socket_udpWrite(SOCKET(self), address, buffer, start, writeSize);
  383. if (bytesWritten)
  384. {
  385. if (bytesWritten < writeSize)
  386. {
  387. return SOCKETERROR("Socket udp write failed");
  388. }
  389. else
  390. {
  391. UArray_removeRange(buffer, start, bytesWritten);
  392. return self;
  393. }
  394. }
  395. else
  396. {
  397. if (Socket_asyncFailed())
  398. {
  399. return SOCKETERROR("Socket udp write failed");
  400. }
  401. else
  402. {
  403. return IONIL(self);
  404. }
  405. }
  406. }
  407. // ----------------------------------
  408. IoObject *IoSocket_setSocketReadBufferSize(IoSocket *self, IoObject *locals, IoMessage *m)
  409. {
  410. //doc Socket setSocketReadBufferSize(numberOfBytes) Sets the read buffer size for the socket. Returns self on success or nil on error.
  411. int size = IoMessage_locals_intArgAt_(m, locals, 0);
  412. int r = setsockopt(SOCKET(self)->fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(int));
  413. return (r == 0) ? self : IONIL(self);
  414. }
  415. IoObject *IoSocket_setSocketWriteBufferSize(IoSocket *self, IoObject *locals, IoMessage *m)
  416. {
  417. //doc Socket setSocketWriteBufferSize(numberOfBytes) Sets the write buffer size for the socket. Returns self on success or nil on error.
  418. int size = IoMessage_locals_intArgAt_(m, locals, 0);
  419. int r = setsockopt(SOCKET(self)->fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int));
  420. return (r == 0) ? self : IONIL(self);
  421. }
  422. IoObject *IoSocket_setSocketReadLowWaterMark(IoSocket *self, IoObject *locals, IoMessage *m)
  423. {
  424. /*doc Socket setSocketReadLowWaterMark(numberOfBytes)
  425. Sets the read low water mark for the socket. Returns self on success or nil on error.
  426. */
  427. int size = IoMessage_locals_intArgAt_(m, locals, 0);
  428. int r = setsockopt(SOCKET(self)->fd, SOL_SOCKET, SO_RCVLOWAT, &size, sizeof(int));
  429. return (r == 0) ? self : IONIL(self);
  430. }
  431. IoObject *IoSocket_setSocketWriteLowWaterMark(IoSocket *self, IoObject *locals, IoMessage *m)
  432. {
  433. /*doc Socket setSocketWriteLowWaterMark(numberOfBytes)
  434. Sets the write low water mark for the socket. Returns self on success or nil on error.
  435. */
  436. int size = IoMessage_locals_intArgAt_(m, locals, 0);
  437. int r = setsockopt(SOCKET(self)->fd, SOL_SOCKET, SO_SNDLOWAT, &size, sizeof(int));
  438. return (r == 0) ? self : IONIL(self);
  439. }
  440. IoObject *IoSocket_getSocketReadLowWaterMark(IoSocket *self, IoObject *locals, IoMessage *m)
  441. {
  442. /*doc Socket getSocketReadLowWaterMark
  443. Returns the read low water mark for the socket on success or nil on error.
  444. */
  445. int size = 0;
  446. socklen_t length = sizeof(int);
  447. //int r =
  448. getsockopt(SOCKET(self)->fd, SOL_SOCKET, SO_RCVLOWAT, &size, &length);
  449. // return (r == 0) ? IONUMBER(size) : IONIL(self);
  450. return IONUMBER(size);
  451. }
  452. IoObject *IoSocket_getSocketWriteLowWaterMark(IoSocket *self, IoObject *locals, IoMessage *m)
  453. {
  454. /*doc Socket getSocketWriteLowWaterMark
  455. Returns the write low water mark for the socket on success or nil on error.
  456. */
  457. int size = 0;
  458. socklen_t length = sizeof(int);
  459. //int r =
  460. getsockopt(SOCKET(self)->fd, SOL_SOCKET, SO_SNDLOWAT, &size, &length);
  461. // return (r == 0) ? IONUMBER(size) : IONIL(self);
  462. return IONUMBER(size);
  463. }
  464. #ifndef WIN32
  465. #include <sys/socket.h>
  466. #endif
  467. IoObject *IoSocket_setNoDelay(IoSocket *self, IoObject *locals, IoMessage *m)
  468. {
  469. /*doc Socket setNoDelay
  470. Sets the socket to be no-delay. Returns self on success or nil on error.
  471. */
  472. int r = -1;
  473. #ifdef TCP_NODELAY
  474. int flag = 1;
  475. r = setsockopt(SOCKET(self)->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
  476. #endif
  477. return (r == 0) ? self : IONIL(self);
  478. }
  479. IoObject *IoSocket_errorNumber(IoSocket *self, IoObject *locals, IoMessage *m)
  480. {
  481. //doc Socket errorNumber Returns the socket error number for the last error.
  482. return IONUMBER(SocketErrorStatus());
  483. }
  484. IoObject *IoSocket_errorDescription(IoSocket *self, IoObject *locals, IoMessage *m)
  485. {
  486. //doc Socket errorDescription Returns a description of the last error on the socket as a string.
  487. return IOSYMBOL(Socket_errorDescription());
  488. }