IoObject *IoSocket_asyncUdpRead(IoSocket *self, IoObject *locals, IoMessage *m) { /*doc Socket asyncUdpRead(ipAddress, aSeq, readSize) Reads up to readSize number of bytes from ipAddress into aSeq if data is available. Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected. */ IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0); UArray *buffer = IoSeq_rawUArray(IoMessage_locals_mutableSeqArgAt_(m, locals, 1)); size_t readSize = IoMessage_locals_sizetArgAt_(m, locals, 2); if (Socket_udpRead(SOCKET(self), IoSocket_rawAddressFrom_(address), buffer, readSize)) { return self; } else { if (Socket_asyncFailed()) { return SOCKETERROR("Socket udp read failed"); } else { return IONIL(self); } } }
IoObject *IoSocket_asyncAccept(IoSocket *self, IoObject *locals, IoMessage *m) { //doc Socket asyncAccept(addressObject) Immediately returns a socket for a connection if one is available or nil otherwise. Returns an Error object on error. IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0); Socket *socket = Socket_accept(SOCKET(self), IoSocket_rawAddressFrom_(address)); if (socket) { IoObject *newSocket = IoSocket_newWithSocket_(IOSTATE, socket); newSocket = IoObject_initClone_(self, locals, m, newSocket); return IoSocket_rawSetupEvents(newSocket, locals, m); } else { if (Socket_asyncFailed()) { return SOCKETERROR("Socket accept failed"); } else { return IONIL(self); } } }
IoObject *IoSocket_setAddress(IoSocket *self, IoObject *locals, IoMessage *m) { //doc Socket address Returns the address (IPAddress or UnixPath) object for the socket. //doc Socket setAddress(addressObject) Sets the address (IPAddress or UnixPath) for the socket. Returns self. For IP sockets the setHost() method should generally be used to set the host instead of this method. For Unix Domain sockets use the setPath() method. IoObject *addr = IoMessage_locals_addressArgAt_(m, locals, 0); SOCKET(self)->af = Address_family(IoSocket_rawAddressFrom_(addr)); IoObject_setSlot_to_(self, IOSYMBOL("address"), addr); return self; }
IoObject *IoSocket_asyncBind(IoSocket *self, IoObject *locals, IoMessage *m) { //doc Socket asyncBind Binds the socket and returns self immediately or an Error object on error. IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0); if (Socket_bind(SOCKET(self), IoSocket_rawAddressFrom_(address))) { return self; } else { return SOCKETERROR("Failed to bind socket"); } }
IoObject *IoSocket_asyncConnect(IoSocket *self, IoObject *locals, IoMessage *m) { //doc Socket asyncConnect(addressObject) Connects to the given Address and returns self or an Error object on error. IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0); if (Socket_connectTo(SOCKET(self), IoSocket_rawAddressFrom_(address))) { return self; } else { if (Socket_connectToFailed()) { return SOCKETERROR("Socket connect failed"); } else { return IONIL(self); } } }
IoSecureSocket *IoSecureServer_dtlsWrap(IoSecureServer *self, IoObject *locals, IoMessage *msg) { SSL_CTX *ctx = OCTX(self); IoSocket *sock = IoObject_getSlot_(self, IOSYMBOL("socket")); IoIPAddress *ioip = IoMessage_locals_addressArgAt_(msg, locals, 0); IPAddress *ip = IoIPAddress_rawIPAddress(ioip); struct sockaddr *addr = IPAddress_sockaddr(ip); IoNumber *port = IoObject_getSlot_(sock, IOSYMBOL("port")); int fd = IoSocket_rawDescriptor(sock); SSL *ssl = SSL_new(ctx); BIO *rbio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(rbio, -1); BIO *wbio = BIO_new_dgram(fd, BIO_NOCLOSE); BIO_dgram_set_peer(wbio, addr); SSL_set_bio(ssl, rbio, wbio); SSL_set_accept_state(ssl); set_nonblocking(wbio); SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); IoSecureSocket *ssock = IoSecureSocket_newWithSSL_IP_(IoObject_state(self), ssl, ioip); return ssock; }
IoObject *IoSocket_asyncUdpWrite(IoSocket *self, IoObject *locals, IoMessage *m) { /*doc Socket asyncUdpWrite(ipAddress, aSeq, startIndex, readSize) Writes readsize bytes from aSeq starting at startIndex to ipAddress. Returns self immediately if successful. Returns an error object on Error. Returns nil if the socket is disconnected. */ IoObject *address = IoMessage_locals_addressArgAt_(m, locals, 0); UArray *buffer = IoSeq_rawUArray(IoMessage_locals_seqArgAt_(m, locals, 1)); size_t start = IoMessage_locals_intArgAt_(m, locals, 2); size_t writeSize = IoMessage_locals_intArgAt_(m, locals, 3); size_t bytesWritten = Socket_udpWrite(SOCKET(self), IoSocket_rawAddressFrom_(address), buffer, start, writeSize); if (bytesWritten) { if (bytesWritten < writeSize) { return SOCKETERROR("Socket udp write failed"); } else { UArray_removeRange(buffer, start, bytesWritten); return self; } } else { if (Socket_asyncFailed()) { return SOCKETERROR("Socket udp write failed"); } else { return IONIL(self); } } }
IPAddress *IoMessage_locals_rawIPAddressArgAt_(IoMessage *self, IoObject *locals, int n) { return IoIPAddress_rawIPAddress(IoMessage_locals_addressArgAt_(self, locals, n)); }