vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Sun Jan 10 23:04:53 2016 +0200| [2f5e439929bfb3675d1e3e1cc3e6ac03c8731f85] | committer: Rémi Denis-Courmont
tls: use I/O vector for receiving > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2f5e439929bfb3675d1e3e1cc3e6ac03c8731f85 --- include/vlc_tls.h | 2 +- modules/access/http/chunked_test.c | 31 +++++++++++++++++++++---------- modules/access/http/h2conn.c | 9 +++++++-- modules/misc/gnutls.c | 33 ++++++++++++++++++++++++--------- modules/misc/securetransport.c | 12 ++++++++---- src/network/tls.c | 23 ++++++++++++++++------- test/modules/misc/tls.c | 4 +++- 7 files changed, 80 insertions(+), 34 deletions(-) diff --git a/include/vlc_tls.h b/include/vlc_tls.h index 224763c..1b65894 100644 --- a/include/vlc_tls.h +++ b/include/vlc_tls.h @@ -42,7 +42,7 @@ struct vlc_tls void *sys; int fd; - ssize_t (*recv)(struct vlc_tls *, void *, size_t); + ssize_t (*readv)(struct vlc_tls *, struct iovec *, unsigned); ssize_t (*writev)(struct vlc_tls *, const struct iovec *, unsigned); int (*shutdown)(struct vlc_tls *, bool duplex); void (*close)(vlc_tls_t *); diff --git a/modules/access/http/chunked_test.c b/modules/access/http/chunked_test.c index 3efac11..90c4edd 100644 --- a/modules/access/http/chunked_test.c +++ b/modules/access/http/chunked_test.c @@ -39,19 +39,30 @@ static const char *stream_content; static size_t stream_length; static bool stream_bad; -static ssize_t recv_callback(struct vlc_tls *tls, void *buf, size_t len) +static ssize_t recv_callback(struct vlc_tls *tls, struct iovec *iov, + unsigned count) { - size_t copy = len; - if (copy > stream_length) - copy = stream_length; - if (copy > 0) + size_t rcvd = 0; + + while (count > 0) { - memcpy(buf, stream_content, copy); - stream_content += copy; - stream_length -= copy; + size_t copy = iov->iov_len; + if (copy > stream_length) + copy = stream_length; + + if (copy > 0) + { + memcpy(iov->iov_base, stream_content, copy); + stream_content += copy; + stream_length -= copy; + rcvd += copy; + } + + iov++; + count--; } (void) tls; - return copy; + return rcvd; } static void close_callback(struct vlc_tls *tls) @@ -61,7 +72,7 @@ static void close_callback(struct vlc_tls *tls) static struct vlc_tls chunked_tls = { - .recv = recv_callback, + .readv = recv_callback, .close = close_callback, }; diff --git a/modules/access/http/h2conn.c b/modules/access/http/h2conn.c index f6d2a01..60ec980 100644 --- a/modules/access/http/h2conn.c +++ b/modules/access/http/h2conn.c @@ -525,15 +525,18 @@ static const struct vlc_h2_parser_cbs vlc_h2_parser_callbacks = static ssize_t vlc_https_recv(vlc_tls_t *tls, void *buf, size_t len) { struct pollfd ufd; + struct iovec iov; size_t count = 0; ufd.fd = tls->fd; ufd.events = POLLIN; + iov.iov_base = buf; + iov.iov_len = len; - while (count < len) + while (iov.iov_len > 0) { int canc = vlc_savecancel(); - ssize_t val = tls->recv(tls, (char *)buf + count, len - count); + ssize_t val = tls->readv(tls, &iov, 1); vlc_restorecancel(canc); @@ -542,6 +545,8 @@ static ssize_t vlc_https_recv(vlc_tls_t *tls, void *buf, size_t len) if (val >= 0) { + iov.iov_base = (char *)iov.iov_base + val; + iov.iov_len -= val; count += val; continue; } diff --git a/modules/misc/gnutls.c b/modules/misc/gnutls.c index 0d0f737..8512516 100644 --- a/modules/misc/gnutls.c +++ b/modules/misc/gnutls.c @@ -157,6 +157,29 @@ static ssize_t vlc_gnutls_writev (gnutls_transport_ptr_t ptr, return sendmsg (fd, &msg, MSG_NOSIGNAL); } +static ssize_t gnutls_Recv(vlc_tls_t *tls, struct iovec *iov, unsigned count) +{ + gnutls_session_t session = tls->sys; + size_t rcvd = 0; + + while (count > 0) + { + ssize_t val = gnutls_record_recv(session, iov->iov_base, iov->iov_len); + if (val < 0) + return rcvd ? (ssize_t)rcvd : gnutls_Error(tls, val); + + rcvd += val; + + if ((size_t)val < iov->iov_len) + break; + + iov++; + count--; + } + + return rcvd; +} + static ssize_t gnutls_Send (vlc_tls_t *tls, const struct iovec *iov, unsigned count) { @@ -182,14 +205,6 @@ static ssize_t gnutls_Send (vlc_tls_t *tls, const struct iovec *iov, return (val < 0) ? gnutls_Error (tls, val) : val; } -static ssize_t gnutls_Recv (vlc_tls_t *tls, void *buf, size_t length) -{ - gnutls_session_t session = tls->sys; - ssize_t val = gnutls_record_recv (session, buf, length); - - return (val < 0) ? gnutls_Error (tls, val) : val; -} - static int gnutls_Shutdown(vlc_tls_t *tls, bool duplex) { gnutls_session_t session = tls->sys; @@ -278,8 +293,8 @@ static int gnutls_SessionOpen(vlc_tls_creds_t *creds, vlc_tls_t *tls, int type, gnutls_transport_set_int (session, fd); gnutls_transport_set_vec_push_function (session, vlc_gnutls_writev); tls->sys = session; + tls->readv = gnutls_Recv; tls->writev = gnutls_Send; - tls->recv = gnutls_Recv; tls->shutdown = gnutls_Shutdown; tls->close = gnutls_Close; return VLC_SUCCESS; diff --git a/modules/misc/securetransport.c b/modules/misc/securetransport.c index 2c3e9b3..afb1d62 100644 --- a/modules/misc/securetransport.c +++ b/modules/misc/securetransport.c @@ -60,7 +60,7 @@ vlc_module_begin () /* * The server module currently uses an OSX only API, to be compatible with 10.6. - * If the module is needed on iOS, then the "modern" keychain lookup API need to be + If the module is needed on iOS, then the "modern" keychain lookup API need to be * implemented. */ #if !TARGET_OS_IPHONE @@ -486,13 +486,17 @@ static ssize_t st_Send (vlc_tls_t *session, const struct iovec *iov, /** * Receives data through a TLS session. */ -static ssize_t st_Recv (vlc_tls_t *session, void *buf, size_t length) +static ssize_t st_Recv (vlc_tls_t *session, struct iovec *iov, unsigned count) { vlc_tls_sys_t *sys = session->sys; assert(sys); + if (unlikely(count == 0)) + return 0; + size_t actualSize; - OSStatus ret = SSLRead(sys->p_context, buf, length, &actualSize); + OSStatus ret = SSLRead(sys->p_context, iov->iov_base, iov->iov_len, + &actualSize); if (ret == errSSLWouldBlock && actualSize) return actualSize; @@ -565,8 +569,8 @@ static int st_SessionOpenCommon (vlc_tls_creds_t *crd, vlc_tls_t *session, sys->p_context = NULL; session->sys = sys; + session->readv = st_Recv; session->writev = st_Send; - session->recv = st_Recv; session->shutdown = st_SessionShutdown; session->close = st_SessionClose; crd->handshake = st_Handshake; diff --git a/src/network/tls.c b/src/network/tls.c index 49adc9e..0b88966 100644 --- a/src/network/tls.c +++ b/src/network/tls.c @@ -220,9 +220,12 @@ error: ssize_t vlc_tls_Read(vlc_tls_t *session, void *buf, size_t len, bool waitall) { struct pollfd ufd; + struct iovec iov; ufd.fd = session->fd; ufd.events = POLLIN; + iov.iov_base = buf; + iov.iov_len = len; for (size_t rcvd = 0;;) { @@ -232,16 +235,16 @@ ssize_t vlc_tls_Read(vlc_tls_t *session, void *buf, size_t len, bool waitall) return -1; } - ssize_t val = session->recv(session, buf, len); + ssize_t val = session->readv(session, &iov, 1); if (val > 0) { if (!waitall) return val; - buf = ((char *)buf) + val; - len -= val; + iov.iov_base = (char *)iov.iov_base + val; + iov.iov_len -= val; rcvd += val; } - if (len == 0 || val == 0) + if (iov.iov_len == 0 || val == 0) return rcvd; if (val == -1 && errno != EINTR && errno != EAGAIN) return rcvd ? (ssize_t)rcvd : -1; @@ -315,9 +318,15 @@ error: return NULL; } -static ssize_t vlc_tls_DummyReceive(vlc_tls_t *tls, void *buf, size_t len) +static ssize_t vlc_tls_DummyReceive(vlc_tls_t *tls, struct iovec *iov, + unsigned count) { - return recv(tls->fd, buf, len, 0); + struct msghdr msg = + { + .msg_iov = iov, + .msg_iovlen = count, + }; + return recvmsg(tls->fd, &msg, 0); } static ssize_t vlc_tls_DummySend(vlc_tls_t *tls, const struct iovec *iov, @@ -349,7 +358,7 @@ vlc_tls_t *vlc_tls_DummyCreate(vlc_object_t *obj, int fd) session->obj = obj; session->fd = fd; - session->recv = vlc_tls_DummyReceive; + session->readv = vlc_tls_DummyReceive; session->writev = vlc_tls_DummySend; session->shutdown = vlc_tls_DummyShutdown; session->close = vlc_tls_DummyClose; diff --git a/test/modules/misc/tls.c b/test/modules/misc/tls.c index 5eb6660..bb54e25 100644 --- a/test/modules/misc/tls.c +++ b/test/modules/misc/tls.c @@ -199,7 +199,9 @@ int main(void) char buf[12]; struct iovec iov; - val = tls->recv(tls, buf, sizeof (buf)); + iov.iov_base = buf; + iov.iov_len = sizeof (buf); + val = tls->readv(tls, &iov, 1); assert(val == -1 && errno == EAGAIN); val = vlc_tls_Write(tls, "Hello ", 6); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
