summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2015-05-17 20:33:48 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2015-05-17 21:11:53 +0200
commit7efa8ba74a506352121c0aaab0190bda0bad6400 (patch)
treef8a4cbb215e45934fdc3478a0a071606a6f64e4c
parent901722312d789125b0e28f59054d3162bbcdc95e (diff)
downloadgnutls-7efa8ba74a506352121c0aaab0190bda0bad6400.tar.gz
Allow the usage of MSG_NOSIGNAL in send functions
That introduces the GNUTLS_NO_SIGNAL flag for gnutls_init(), which is available in systems that support the MSG_NOSIGNAL flag to send(). That eases the usage of the library within other libraries. Resolves #11
-rw-r--r--lib/gnutls_state.c13
-rw-r--r--lib/includes/gnutls/gnutls.h.in2
-rw-r--r--lib/system.c17
-rw-r--r--lib/system.h2
4 files changed, 28 insertions, 6 deletions
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index e3463d9b07..ef2a587f9e 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -288,10 +288,8 @@ void _gnutls_handshake_internal_state_clear(gnutls_session_t session)
* be allocated. This function allocates structures which can only
* be free'd by calling gnutls_deinit(). Returns %GNUTLS_E_SUCCESS (0) on success.
*
- * @flags can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER. For a DTLS
- * entity, the flags %GNUTLS_DATAGRAM and %GNUTLS_NONBLOCK are
- * also available. The latter flag will indicated non-blocking
- * operation of the sockets provided to gnutls.
+ * @flags can be one of %GNUTLS_CLIENT, %GNUTLS_SERVER, %GNUTLS_DATAGRAM,
+ * %GNUTLS_NONBLOCK or %GNUTLS_NOSIGNAL (since 3.4.2).
*
* The flag %GNUTLS_NO_REPLAY_PROTECTION will disable any
* replay protection in DTLS mode. That must only used when
@@ -376,7 +374,12 @@ int gnutls_init(gnutls_session_t * session, unsigned int flags)
(*session)->internals.priorities.sr = SR_PARTIAL;
#ifdef HAVE_WRITEV
- gnutls_transport_set_vec_push_function(*session, system_writev);
+#ifdef MSG_NOSIGNAL
+ if (flags & GNUTLS_NO_SIGNAL)
+ gnutls_transport_set_vec_push_function(*session, system_writev_nosignal);
+ else
+#endif
+ gnutls_transport_set_vec_push_function(*session, system_writev);
#else
gnutls_transport_set_push_function(*session, system_write);
#endif
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 010ffff131..49c4805add 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -322,6 +322,7 @@ typedef enum {
* @GNUTLS_CLIENT: Connection end is a client.
* @GNUTLS_DATAGRAM: Connection is datagram oriented (DTLS).
* @GNUTLS_NONBLOCK: Connection should not block.
+ * @GNUTLS_NO_SIGNAL: In systems where SIGPIPE is delivered on send, it will be disabled. That flag has effect in systems which support the MSG_NOSIGNAL sockets flag.
* @GNUTLS_NO_EXTENSIONS: Do not enable any TLS extensions by default.
* @GNUTLS_NO_REPLAY_PROTECTION: Disable any replay protection in DTLS.
*
@@ -332,6 +333,7 @@ typedef enum {
#define GNUTLS_NONBLOCK (1<<3)
#define GNUTLS_NO_EXTENSIONS (1<<4)
#define GNUTLS_NO_REPLAY_PROTECTION (1<<5)
+#define GNUTLS_NO_SIGNAL (1<<6)
/**
* gnutls_alert_level_t:
diff --git a/lib/system.c b/lib/system.c
index d336b529b1..f12dbfc2f3 100644
--- a/lib/system.c
+++ b/lib/system.c
@@ -110,16 +110,31 @@ int system_errno(gnutls_transport_ptr_t ptr)
return errno;
}
+#ifdef MSG_NOSIGNAL
+ssize_t
+system_writev_nosignal(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
+ int iovec_cnt)
+{
+ struct msghdr hdr;
+
+ memset(&hdr, 0, sizeof(hdr));
+ hdr.msg_iov = (struct iovec *)iovec;
+ hdr.msg_iovlen = iovec_cnt;
+
+ return sendmsg(GNUTLS_POINTER_TO_INT(ptr), &hdr, MSG_NOSIGNAL);
+}
+#endif
+
ssize_t
system_writev(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
int iovec_cnt)
{
return writev(GNUTLS_POINTER_TO_INT(ptr), (struct iovec *) iovec,
iovec_cnt);
-
}
#endif
+
ssize_t
system_read(gnutls_transport_ptr_t ptr, void *data, size_t data_size)
{
diff --git a/lib/system.h b/lib/system.h
index 03cf7fd494..23d291d41d 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -48,6 +48,8 @@ ssize_t system_write(gnutls_transport_ptr_t ptr, const void *data,
#define HAVE_WRITEV
ssize_t system_writev(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
int iovec_cnt);
+ssize_t system_writev_nosignal(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
+ int iovec_cnt);
#endif
ssize_t system_read(gnutls_transport_ptr_t ptr, void *data,
size_t data_size);