/addons/Socket/source/IoSocket.c

https://github.com/richcollins/io · C · 598 lines · 401 code · 104 blank · 93 comment · 38 complexity · 2b562da95f86386da124c4a530adcfc0 MD5 · raw file

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