int net_write2(net_t * net, char * buf, unsigned int len) { uv_write_t * req; uv_buf_t uvbuf; int read = 0; req = (uv_write_t *) malloc(sizeof(uv_write_t)); req->data = net; switch (net->use_ssl) { case USE_SSL: tls_write(net->tls, buf, (int)len); do { read = tls_bio_read(net->tls, 0); if (read > 0) { uvbuf = uv_buf_init(net->tls->buf, read); uv_write(req, (uv_stream_t*)net->handle, &uvbuf, 1, net_write_cb); } } while (read > 0); break; case NOT_SSL: uvbuf = uv_buf_init(buf, len); uv_write(req, (uv_stream_t*)net->handle, &uvbuf, 1, net_write_cb); break; } return NET_OK; }
void net_connect_cb(uv_connect_t *conn, int stat) { net_t * net = (net_t *) conn->data; err_t err; int read; if (stat < 0) { err = uv_last_error(net->loop); if (net->error_cb) { net->error_cb(net, err, (char *) uv_strerror(err)); } else { printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(err)); net_free(net); } return; } /* * change the `connected` state */ net->connected = 1; /* * read buffers via uv */ uv_read_start((uv_stream_t *) net->handle, net_alloc, net_read); /* * call `conn_cb`, the tcp connection has been * established in user-land. */ if (net->use_ssl == NOT_SSL && net->conn_cb != NULL) { net->conn_cb(net); } /* * Handle TLS Partial */ if (net->use_ssl == USE_SSL && tls_connect(net->tls) == NET_OK) { read = 0; do { read = tls_bio_read(net->tls, 0); if (read > 0) { uv_write_t req; uv_buf_t uvbuf = uv_buf_init(net->tls->buf, read); uv_write(&req, (uv_stream_t*)net->handle, &uvbuf, 1, NULL); } } while (read > 0); } }
static ssize_t tls_timed_read(int fd, void *buf, size_t len, int timeout, void *context) { const char *myname = "tls_timed_read"; ssize_t ret; TLS_SESS_STATE *TLScontext; TLScontext = (TLS_SESS_STATE *) context; if (!TLScontext) acl_msg_panic("%s: no context", myname); ret = tls_bio_read(fd, buf, (int) len, timeout, TLScontext); if (ret > 0 && TLScontext->log_level >= 4) acl_msg_info("Read %ld chars: %.*s", (long) ret, (int) (ret > 40 ? 40 : ret), (char *) buf); return (ret); }
void net_read(uv_stream_t *handle, ssize_t nread, const uv_buf_t buf) { net_t * net = (net_t *) handle->data; err_t err; if (nread < 0) { err = uv_last_error(net->loop); if (net->error_cb) { net->error_cb(net, err, (char *) uv_strerror(err)); } else { printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(err)); net_free(net); } return; } /* * BIO Return rule: * All these functions return either the amount of data successfully * read or written (if the return value is positive) or that no data * was successfully read or written if the result is 0 or -1. If the * return value is -2 then the operation is not implemented in the specific BIO type. */ if (net->use_ssl) { net->tls->data = malloc(1); tls_bio_write(net->tls, buf.base, nread); free(buf.base); int read = 0; int stat = tls_read(net->tls); if (stat == 1) { /* * continue: Say hello */ do { read = tls_bio_read(net->tls, 0); if (read > 0) { uv_write_t req; uv_buf_t uvbuf = uv_buf_init(net->tls->buf, read); uv_write(&req, (uv_stream_t*)net->handle, &uvbuf, 1, NULL); } } while (read > 0); } else if (stat == 0) { /* * SSL Connection is created * Here need to call user-land callback */ uv_read_stop((uv_stream_t*)net->handle); if (net->read_cb != NULL) { net->read_cb(net, buffer_length(net->tls->buffer), buffer_string(net->tls->buffer)); } } else if (stat == -1) { /* * Just connection in SSL * call `conn_cb`, the ssl connection has been * established in user-land. */ if (net->conn_cb != NULL) { net->conn_cb(net); } } else { /* * TODO(Yorkie): HOWTO */ } return; } /* * TCP Part, no SSL, just proxy of uv. */ uv_read_stop(handle); buf.base[nread] = 0; if (net->read_cb != NULL) { net->read_cb(net, nread, buf.base); } }