[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.7 Data transfer and termination
Once the handshake is complete and peer’s identity
has been verified data can be exchanged. The available
functions resemble the POSIX recv
and send
functions. It is suggested to use gnutls_error_is_fatal
to check whether the error codes returned by these functions are
fatal for the protocol or can be ignored.
- Function: ssize_t gnutls_record_send (gnutls_session_t session, const void * data, size_t data_size)
session: is a
gnutls_session_t
structure.data: contains the data to send
data_size: is the length of the data
This function has the similar semantics with
send()
. The only difference is that it accepts a GnuTLS session, and uses different error codes. Note that if the send buffer is full,send()
will block this function. See thesend()
documentation for full information. You can replace the default push function by usinggnutls_transport_set_ptr2()
with a call tosend()
with a MSG_DONTWAIT flag if blocking is a problem. If the EINTR is returned by the internal push function (the default issend()
) thenGNUTLS_E_INTERRUPTED
will be returned. IfGNUTLS_E_INTERRUPTED
orGNUTLS_E_AGAIN
is returned, you must call this function again, with the same parameters; alternatively you could provide aNULL
pointer for data, and 0 for size. cf.gnutls_record_get_direction()
.Note that in DTLS this function will return the
GNUTLS_E_LARGE_PACKET
error code if the send data exceed the data MTU value - as returned bygnutls_dtls_get_data_mtu()
. The errno value EMSGSIZE also maps toGNUTLS_E_LARGE_PACKET
.Returns: The number of bytes sent, or a negative error code. The number of bytes sent might be less than
data_size
. The maximum number of bytes this function can send in a single call depends on the negotiated maximum record size.
- Function: ssize_t gnutls_record_recv (gnutls_session_t session, void * data, size_t data_size)
session: is a
gnutls_session_t
structure.data: the buffer that the data will be read into
data_size: the number of requested bytes
This function has the similar semantics with
recv()
. The only difference is that it accepts a GnuTLS session, and uses different error codes. In the special case that a server requests a renegotiation, the client may receive an error code ofGNUTLS_E_REHANDSHAKE
. This message may be simply ignored, replied with an alertGNUTLS_A_NO_RENEGOTIATION
, or replied with a new handshake, depending on the client’s will. IfEINTR
is returned by the internal push function (the default isrecv()
) thenGNUTLS_E_INTERRUPTED
will be returned. IfGNUTLS_E_INTERRUPTED
orGNUTLS_E_AGAIN
is returned, you must call this function again to get the data. See alsognutls_record_get_direction()
. A server may also receiveGNUTLS_E_REHANDSHAKE
when a client has initiated a handshake. In that case the server can only initiate a handshake or terminate the connection.Returns: The number of bytes received and zero on EOF (for stream connections). A negative error code is returned in case of an error. The number of bytes received might be less than the requested
data_size
.
- Function: int gnutls_error_is_fatal (int error)
error: is a GnuTLS error code, a negative error code
If a GnuTLS function returns a negative error code you may feed that value to this function to see if the error condition is fatal to a TLS session (i.e., must be terminated).
Note that you may also want to check the error code manually, since some non-fatal errors to the protocol (such as a warning alert or a rehandshake request) may be fatal for your program.
This function is only useful if you are dealing with errors from functions that relate to a TLS session (e.g., record layer or handshake layer handling functions).
Returns: zero on non fatal errors or positive
error
values. Non-zero on fatal error codes.
Although, in the TLS protocol the receive function can be called at any time, when DTLS is used the GnuTLS receive functions must be called once a message is available for reading, even if no data are expected. This is because in DTLS various (internal) actions may be required due to retransmission timers. Moreover, an extended receive function is shown below, which allows the extraction of the message’s sequence number. Due to the unreliable nature of the protocol, this field allows distinguishing out-of-order messages.
- Function: ssize_t gnutls_record_recv_seq (gnutls_session_t session, void * data, size_t data_size, unsigned char * seq)
session: is a
gnutls_session_t
structure.data: the buffer that the data will be read into
data_size: the number of requested bytes
seq: is the packet’s 64-bit sequence number. Should have space for 8 bytes.
This function is the same as
gnutls_record_recv()
, except that it returns in addition to data, the sequence number of the data. This is useful in DTLS where record packets might be received out-of-order. The returned 8-byte sequence number is an integer in big-endian format and should be treated as a unique message identification.Returns: The number of bytes received and zero on EOF. A negative error code is returned in case of an error. The number of bytes received might be less than
data_size
.Since: 3.0
The gnutls_record_check_pending helper function is available to
allow checking whether data are available to be read in a GnuTLS session
buffers. Note that this function complements but does not replace select
,
i.e., gnutls_record_check_pending reports no data to be read, select
should be called to check for data in the network buffers.
- Function: size_t gnutls_record_check_pending (gnutls_session_t session)
session: is a
gnutls_session_t
structure.This function checks if there are unread data in the gnutls buffers. If the return value is non-zero the next call to
gnutls_record_recv()
is guaranteed not to block.Returns: Returns the size of the data or zero.
int gnutls_record_get_direction (gnutls_session_t session)
Once a TLS or DTLS session is no longer needed, it is recommended to use gnutls_bye to terminate the session. That way the peer is notified securely about the intention of termination, which allows distinguishing it from a malicious connection termination. A session can be deinitialized with the gnutls_deinit function.
- Function: int gnutls_bye (gnutls_session_t session, gnutls_close_request_t how)
session: is a
gnutls_session_t
structure.how: is an integer
Terminates the current TLS/SSL connection. The connection should have been initiated using
gnutls_handshake()
.how
should be one ofGNUTLS_SHUT_RDWR
,GNUTLS_SHUT_WR
.In case of
GNUTLS_SHUT_RDWR
the TLS session gets terminated and further receives and sends will be disallowed. If the return value is zero you may continue using the underlying transport layer.GNUTLS_SHUT_RDWR
sends an alert containing a close request and waits for the peer to reply with the same message.In case of
GNUTLS_SHUT_WR
the TLS session gets terminated and further sends will be disallowed. In order to reuse the connection you should wait for an EOF from the peer.GNUTLS_SHUT_WR
sends an alert containing a close request.Note that not all implementations will properly terminate a TLS connection. Some of them, usually for performance reasons, will terminate only the underlying transport layer, and thus not distinguishing between a malicious party prematurely terminating the connection and normal termination.
This function may also return
GNUTLS_E_AGAIN
orGNUTLS_E_INTERRUPTED
; cf.gnutls_record_get_direction()
.Returns:
GNUTLS_E_SUCCESS
on success, or an error code, see function documentation for entire semantics.
- Function: void gnutls_deinit (gnutls_session_t session)
session: is a
gnutls_session_t
structure.This function clears all buffers associated with the
session
. This function will also remove session data from the session database if the session was terminated abnormally.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on February 9, 2014 using texi2html 5.0.