Exemple #1
0
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;		
}
Exemple #2
0
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;	
}