[vlc-commits] tls: use I/O vector for receiving
Rémi Denis-Courmont
git at videolan.org
Wed Jan 13 21:49:49 CET 2016
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | 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);
More information about the vlc-commits
mailing list