static inline int datagam_socket_send(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; errno = 0; if(h->status != SOCKET_DATAGRAM){ return -1; } if(0 != kn_list_size(&s->pending_send)) return kn_sock_post_recv(h,req); struct msghdr _msghdr = { .msg_name = &req->addr, .msg_namelen = sizeof(req->addr), .msg_iov = req->iovec, .msg_iovlen = req->iovec_count, .msg_flags = 0, .msg_control = NULL, .msg_controllen = 0 }; return TEMP_FAILURE_RETRY(sendmsg(s->comm_head.fd,&_msghdr,0)); } int kn_sock_send(handle_t h,st_io *req){ if(h->type != KN_SOCKET){ return -1; } if(((kn_socket*)h)->type == SOCK_STREAM) return stream_socket_send(h,req); else if(((kn_socket*)h)->type == SOCK_DGRAM) return datagam_socket_send(h,req); else return -1; } static inline int stream_socket_recv(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; errno = 0; if(!s->e || h->status != SOCKET_ESTABLISH){ return -1; } if(0 != kn_list_size(&s->pending_recv)) return kn_sock_post_recv(h,req); int bytes_transfer = 0; if(((kn_stream_socket*)s)->ssl){ bytes_transfer = TEMP_FAILURE_RETRY(SSL_read(((kn_stream_socket*)s)->ssl,req->iovec[0].iov_base,req->iovec[0].iov_len)); int ssl_error = SSL_get_error(((kn_stream_socket*)s)->ssl,bytes_transfer); if(bytes_transfer < 0 && (ssl_error == SSL_ERROR_WANT_WRITE || ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_X509_LOOKUP)){ errno = EAGAIN; } } else bytes_transfer = TEMP_FAILURE_RETRY(readv(h->fd,req->iovec,req->iovec_count)); if(bytes_transfer < 0 && errno == EAGAIN) return kn_sock_post_recv(h,req); return bytes_transfer > 0 ? bytes_transfer:-1; }
static inline int datagam_socket_recv(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; errno = 0; if(!s->e || h->status != SOCKET_DATAGRAM){ return -1; } if(0 != kn_list_size(&s->pending_recv)) return kn_sock_post_recv(h,req); struct msghdr _msghdr = { .msg_name = &req->addr, .msg_namelen = sizeof(req->addr), .msg_iov = req->iovec, .msg_iovlen = req->iovec_count, .msg_flags = 0, .msg_control = NULL, .msg_controllen = 0 }; req->recvflags = 0; int bytes_transfer = TEMP_FAILURE_RETRY(recvmsg(s->comm_head.fd,&_msghdr,0)); req->recvflags = _msghdr.msg_flags; if(bytes_transfer < 0 && errno == EAGAIN) return kn_sock_post_recv(h,req); return bytes_transfer > 0 ? bytes_transfer:-1; } int kn_sock_recv(handle_t h,st_io *req){ if(h->type != KN_SOCKET){ return -1; } if(((kn_socket*)h)->type == SOCK_STREAM) return stream_socket_recv(h,req); else if(((kn_socket*)h)->type == SOCK_DGRAM) return datagam_socket_recv(h,req); else return -1; } static inline int stream_socket_post_send(handle_t h,st_io *req){ kn_socket *s = (kn_socket*)h; if(!s->e || h->status != SOCKET_ESTABLISH){ return -1; } if(((kn_stream_socket*)s)->ssl){ assert(req->iovec_count == 1); if(req->iovec_count != 1) return -1; } if(!is_set_write(h)){ if(0 != kn_enable_write(s->e,h)) return -1; } kn_list_pushback(&s->pending_send,(kn_list_node*)req); return 0; }