BIO_s_dgram: add documentation and hazard warnings
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19795)
This commit is contained in:
parent
a167e048a4
commit
408622b73a
@ -651,6 +651,10 @@ DEPEND[html/man3/BIO_s_core.html]=man3/BIO_s_core.pod
|
||||
GENERATE[html/man3/BIO_s_core.html]=man3/BIO_s_core.pod
|
||||
DEPEND[man/man3/BIO_s_core.3]=man3/BIO_s_core.pod
|
||||
GENERATE[man/man3/BIO_s_core.3]=man3/BIO_s_core.pod
|
||||
DEPEND[html/man3/BIO_s_datagram.html]=man3/BIO_s_datagram.pod
|
||||
GENERATE[html/man3/BIO_s_datagram.html]=man3/BIO_s_datagram.pod
|
||||
DEPEND[man/man3/BIO_s_datagram.3]=man3/BIO_s_datagram.pod
|
||||
GENERATE[man/man3/BIO_s_datagram.3]=man3/BIO_s_datagram.pod
|
||||
DEPEND[html/man3/BIO_s_dgram_pair.html]=man3/BIO_s_dgram_pair.pod
|
||||
GENERATE[html/man3/BIO_s_dgram_pair.html]=man3/BIO_s_dgram_pair.pod
|
||||
DEPEND[man/man3/BIO_s_dgram_pair.3]=man3/BIO_s_dgram_pair.pod
|
||||
@ -2958,6 +2962,7 @@ html/man3/BIO_s_accept.html \
|
||||
html/man3/BIO_s_bio.html \
|
||||
html/man3/BIO_s_connect.html \
|
||||
html/man3/BIO_s_core.html \
|
||||
html/man3/BIO_s_datagram.html \
|
||||
html/man3/BIO_s_dgram_pair.html \
|
||||
html/man3/BIO_s_fd.html \
|
||||
html/man3/BIO_s_file.html \
|
||||
@ -3569,6 +3574,7 @@ man/man3/BIO_s_accept.3 \
|
||||
man/man3/BIO_s_bio.3 \
|
||||
man/man3/BIO_s_connect.3 \
|
||||
man/man3/BIO_s_core.3 \
|
||||
man/man3/BIO_s_datagram.3 \
|
||||
man/man3/BIO_s_dgram_pair.3 \
|
||||
man/man3/BIO_s_fd.3 \
|
||||
man/man3/BIO_s_file.3 \
|
||||
|
255
doc/man3/BIO_s_datagram.pod
Normal file
255
doc/man3/BIO_s_datagram.pod
Normal file
@ -0,0 +1,255 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
BIO_s_datagram, BIO_new_dgram,
|
||||
BIO_ctrl_dgram_connect,
|
||||
BIO_ctrl_set_connected,
|
||||
BIO_dgram_recv_timedout,
|
||||
BIO_dgram_send_timedout,
|
||||
BIO_dgram_get_peer,
|
||||
BIO_dgram_set_peer,
|
||||
BIO_dgram_get_mtu_overhead - Network BIO with datagram semantics
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
BIO_METHOD *BIO_s_datagram(void);
|
||||
BIO *BIO_new_dgram(int fd, int close_flag);
|
||||
|
||||
int BIO_ctrl_dgram_connect(BIO *bio, const BIO_ADDR *peer);
|
||||
int BIO_ctrl_set_connected(BIO *bio, const BIO_ADDR *peer);
|
||||
int BIO_dgram_recv_timedout(BIO *bio);
|
||||
int BIO_dgram_send_timedout(BIO *bio);
|
||||
int BIO_dgram_get_peer(BIO *bio, BIO_ADDR *peer);
|
||||
int BIO_dgram_set_peer(BIO *bio, const BIO_ADDR *peer);
|
||||
int BIO_dgram_get_mtu_overhead(BIO *bio);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
BIO_s_datagram() is a BIO implementation designed for use with network sockets
|
||||
which provide datagram semantics, such as UDP sockets. It is suitable for use
|
||||
with DTLSv1 or QUIC.
|
||||
|
||||
Because BIO_s_datagram() has datagram semantics, a single BIO_write() call sends
|
||||
a single datagram and a single BIO_read() call receives a single datagram. If
|
||||
the size of the buffer passed to BIO_read() is inadequate, the datagram is
|
||||
silently truncated.
|
||||
|
||||
For a memory-based BIO which provides datagram semantics identical to those of
|
||||
BIO_s_datagram(), see L<BIO_s_dgram_pair(3)>.
|
||||
|
||||
This BIO supports the L<BIO_sendmmsg(3)> and L<BIO_recvmmsg(3)> functions.
|
||||
|
||||
When using BIO_s_datagram(), it is important to note that:
|
||||
|
||||
=over 4
|
||||
|
||||
=item
|
||||
|
||||
This BIO can be used with either a connected or unconnected network socket. A
|
||||
connected socket is a network socket which has had L<BIO_connect(3)> or a
|
||||
similar OS-specific function called on it. Such a socket can only receive
|
||||
datagrams from the specified peer. Any other socket is an unconnected socket and
|
||||
can receive datagrams from any host.
|
||||
|
||||
=item
|
||||
|
||||
Despite their naming,
|
||||
neither BIO_ctrl_dgram_connect() nor BIO_ctrl_set_connected() cause a socket
|
||||
to become connected. These controls are provided to indicate to the BIO how
|
||||
the underlying socket is configured and how it is to be used; see below.
|
||||
|
||||
=item
|
||||
|
||||
Use of BIO_s_datagram() with an unconnected network socket is hazardous hecause
|
||||
any successful call to BIO_read() results in the peer address used for any
|
||||
subsequent call to BIO_write() being set to the source address of the datagram
|
||||
received by that call to BIO_read(). Thus, unless the caller calls
|
||||
BIO_dgram_set_peer() immediately prior to every call to BIO_write(), or never
|
||||
calls BIO_read(), any host on the network may cause future datagrams written to
|
||||
be redirected to that host. Therefore, it is recommended that users either use
|
||||
BIO_s_dgram() only with a connected socket, or, if using BIO_s_dgram() with an
|
||||
unconnected socket, to use the L<BIO_sendmmsg(3)> and L<BIO_recvmmsg(3)> methods
|
||||
only and forego use of L<BIO_read(3)> and L<BIO_write(3)>. An exception is where
|
||||
L<DTLSv1_listen(3)> must be used; see L<DTLSv1_listen(3)> for further
|
||||
discussion.
|
||||
|
||||
=item
|
||||
|
||||
Unlike L<BIO_read(3)> and L<BIO_write(3)>, the L<BIO_sendmmsg(3)> and
|
||||
L<BIO_recvmmsg(3)> methods are stateless and do not cause the internal state of
|
||||
the BIO_s_datagram() to change.
|
||||
|
||||
=back
|
||||
|
||||
Various controls are available for configuring the BIO_s_datagram() using
|
||||
L<BIO_ctrl(3)>:
|
||||
|
||||
=over 4
|
||||
|
||||
=item BIO_ctrl_dgram_connect (BIO_CTRL_DGRAM_CONNECT)
|
||||
|
||||
This is equivalent to calling L<BIO_dgram_set_peer(3)>.
|
||||
|
||||
Despite its name, this function does not cause the underlying socket to become
|
||||
connected.
|
||||
|
||||
=item BIO_ctrl_set_connected (BIO_CTRL_SET_CONNECTED)
|
||||
|
||||
This informs the BIO_s_datagram() whether the underlying socket has been
|
||||
connected, and therefore how the BIO_s_datagram() should attempt to use the
|
||||
socket.
|
||||
|
||||
If the I<peer> argument is non-NULL, BIO_s_datagram() assumes that the
|
||||
underlying socket has been connected and will attempt to use the socket using OS
|
||||
APIs which do not specify peer addresses (for example, send(3) and recv(3) or
|
||||
similar). The I<peer> argument should specify the peer address to which the socket
|
||||
is connected.
|
||||
|
||||
If the I<peer> argument is NULL, BIO_s_datagram() assumes that the underlying
|
||||
socket is not connected and will attempt to use the socket using an OS APIs
|
||||
which specify peer addresses (for example, sendto(3) and recvfrom(3)).
|
||||
|
||||
This control does not affect the operation of L<BIO_sendmmsg(3)> or
|
||||
L<BIO_recvmmsg(3)>.
|
||||
|
||||
=item BIO_dgram_get_peer (BIO_CTRL_DGRAM_GET_PEER)
|
||||
|
||||
This outputs a B<BIO_ADDR> which specifies one of the following values,
|
||||
whichever happened most recently:
|
||||
|
||||
=over 4
|
||||
|
||||
=item
|
||||
|
||||
The peer address last passed to BIO_dgram_set_peer(), BIO_ctrl_dgram_connect()
|
||||
or BIO_ctrl_set_connected().
|
||||
|
||||
=item
|
||||
|
||||
The peer address of the datagram last received by a call to BIO_read().
|
||||
|
||||
=back
|
||||
|
||||
=item BIO_dgram_set_peer (BIO_CTRL_DGRAM_SET_PEER)
|
||||
|
||||
Sets the peer address to be used for subsequent writes to this BIO.
|
||||
|
||||
Warning: When used with an unconnected network socket, the value set may be
|
||||
modified by future calls to L<BIO_read(3)>, making use of BIO_s_datagram()
|
||||
hazardous when used with unconnected network sockets; see above.
|
||||
|
||||
This does not affect the operation of L<BIO_sendmmsg(3)>.
|
||||
L<BIO_recvmmsg(3)> does not affect the value set by BIO_dgram_set_peer().
|
||||
|
||||
=item BIO_dgram_recv_timeout (BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP)
|
||||
|
||||
Returns 1 if the last I/O operation performed on the BIO (for example, via a
|
||||
call to L<BIO_read(3)>) may have been caused by a receive timeout.
|
||||
|
||||
=item BIO_dgram_send_timedout (BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP)
|
||||
|
||||
Returns 1 if the last I/O operation performed on the BIO (for example, via a
|
||||
call to L<BIO_write(3)>) may have been caused by a send timeout.
|
||||
|
||||
=item BIO_dgram_get_mtu_overhead (BIO_CTRL_DGRAM_GET_MTU_OVERHEAD)
|
||||
|
||||
Returns a quantity in bytes which is a rough estimate of the number of bytes of
|
||||
overhead which should typically be added to a datagram payload size in order to
|
||||
estimate the final size of the Layer 3 (e.g. IP) packet which will contain the
|
||||
datagram. In most cases, the maximum datagram payload size which can be
|
||||
transmitted can be determined by determining the link MTU in bytes and
|
||||
subtracting the value returned by this call.
|
||||
|
||||
The value returned by this call depends on the network layer protocol being
|
||||
used.
|
||||
|
||||
The value returned is not fully reliable because datagram overheads can be
|
||||
higher in atypical network configurations, for example where IPv6 extension
|
||||
headers or IPv4 options are used.
|
||||
|
||||
=item BIO_CTRL_DGRAM_SET_DONT_FRAG
|
||||
|
||||
If I<num> is nonzero, configures the underlying network socket to enable Don't
|
||||
Fragment mode, in which datagrams will be set with the IP Don't Fragment (DF)
|
||||
bit set. If I<num> is zero, Don't Fragment mode is disabled.
|
||||
|
||||
=item BIO_CTRL_DGRAM_QUERY_MTU
|
||||
|
||||
Queries the OS for its assessment of the Path MTU for the destination to which
|
||||
the underlying network socket, and returns that Path MTU in bytes. This control
|
||||
can only be used with a connected socket.
|
||||
|
||||
This is not supported on all platforms and depends on OS support being
|
||||
available. Returns 0 on failure.
|
||||
|
||||
=item BIO_CTRL_DGRAM_MTU_DISCOVER
|
||||
|
||||
This control requests that Path MTU discovery be enabled on the underlying
|
||||
network socket.
|
||||
|
||||
=item BIO_CTRL_DGRAM_GET_FALLBACK_MTU
|
||||
|
||||
Returns the estimated minimum size of datagram payload which should always be
|
||||
supported on the BIO. This size is determined by the minimum MTU required to be
|
||||
supported by the applicable underlying network layer. Use of datagrams of this
|
||||
size may lead to suboptimal performance, but should be routable in all
|
||||
circumstances. The value returned is the datagram payload size in bytes and does
|
||||
not include the size of layer 3 or layer 4 protocol headers.
|
||||
|
||||
=item BIO_CTRL_DGRAM_MTU_EXCEEDED
|
||||
|
||||
Returns 1 if the last attempted write to the BIO failed due to the size of the
|
||||
attempted write exceeding the applicable MTU.
|
||||
|
||||
=item BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
|
||||
|
||||
Accepts a pointer to a B<struct timeval>. If the time specified is zero,
|
||||
disables receive timeouts. Otherwise, configures the specified time interval as
|
||||
the receive timeout for the socket for the purposes of future L<BIO_read(3)>
|
||||
calls.
|
||||
|
||||
=item BIO_CTRL_DGRAM_SET_PEEK_MODE
|
||||
|
||||
If B<num> is nonzero, enables peek mode; otherwise, disables peek mode. Where
|
||||
peek mode is enabled, calls to L<BIO_read(3)> read datagrams from the underlying
|
||||
network socket in peek mode, meaning that a future call to L<BIO_read(3)> will
|
||||
yield the same datagram until peek mode is disabled.
|
||||
|
||||
L<BIO_recvmmsg(3)> is not affected by this control.
|
||||
|
||||
=back
|
||||
|
||||
BIO_new_dgram() is a helper function which instantiates a BIO_s_datagram() and
|
||||
sets the BIO to use the socket given in I<fd> by calling BIO_set_fd().
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
BIO_s_datagram() returns a BIO method.
|
||||
|
||||
BIO_new_dgram() returns a BIO on success and NULL on failure.
|
||||
|
||||
BIO_ctrl_dgram_connect(), BIO_ctrl_set_connected(),
|
||||
BIO_dgram_get_peer(), BIO_dgram_set_peer() return 1 on success and 0 on failure.
|
||||
|
||||
BIO_dgram_recv_timedout() and BIO_dgram_send_timedout() return 0 or 1 depending
|
||||
on the circumstance; see discussion above.
|
||||
|
||||
BIO_dgram_get_mtu_overhead() returns a value in bytes.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<BIO_sendmmsg(3)>, L<BIO_s_dgram_pair(3)>, L<DTLSv1_listen(3)>, L<bio(7)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
this file except in compliance with the License. You can obtain a copy
|
||||
in the file LICENSE in the source distribution or at
|
||||
L<https://www.openssl.org/source/license.html>.
|
||||
|
||||
=cut
|
@ -64,6 +64,23 @@ does not support this), then B<*peer> will be cleared and the family set to
|
||||
AF_UNSPEC. Typically user code is expected to "connect" the underlying socket to
|
||||
the peer and continue the handshake in a connected state.
|
||||
|
||||
Warning: It is essential that the calling code connects the underlying socket to
|
||||
the peer after making use of DTLSv1_listen(). In the typical case where
|
||||
L<BIO_s_datagram(3)> is used, the peer address is updated when receiving a
|
||||
datagram on an unconnected socket. If the socket is not connected, it can
|
||||
receive datagrams from any host on the network, which will cause subsequent
|
||||
outgoing datagrams transmitted by DTLS to be transmitted to that host. In other
|
||||
words, failing to call BIO_connect() or a similar OS-specific function on a
|
||||
socket means that any host on the network can cause outgoing DTLS traffic to be
|
||||
redirected to it by sending a datagram to the socket in question. This does not
|
||||
break the cryptographic protections of DTLS but may facilitate a
|
||||
denial-of-service attack or allow unencrypted information in the DTLS handshake
|
||||
to be learned by an attacker. This is due to the historical design of
|
||||
L<BIO_s_datagram(3)>; see L<BIO_s_datagram(3)> for details on this issue.
|
||||
|
||||
Once a socket has been connected, L<BIO_ctrl_set_connected(3)> should be used to
|
||||
inform the BIO that the socket is to be used in connected mode.
|
||||
|
||||
Prior to calling DTLSv1_listen() user code must ensure that cookie generation
|
||||
and verification callbacks have been set up using
|
||||
L<SSL_CTX_set_cookie_generate_cb(3)> and L<SSL_CTX_set_cookie_verify_cb(3)>
|
||||
|
@ -201,7 +201,6 @@ BIO_indent(3)
|
||||
BIO_method_name(3)
|
||||
BIO_new_NDEF(3)
|
||||
BIO_new_PKCS7(3)
|
||||
BIO_new_dgram(3)
|
||||
BIO_new_dgram_sctp(3)
|
||||
BIO_nread(3)
|
||||
BIO_nread0(3)
|
||||
@ -209,7 +208,6 @@ BIO_number_read(3)
|
||||
BIO_number_written(3)
|
||||
BIO_nwrite(3)
|
||||
BIO_nwrite0(3)
|
||||
BIO_s_datagram(3)
|
||||
BIO_s_datagram_sctp(3)
|
||||
BIO_s_log(3)
|
||||
BIO_set_flags(3)
|
||||
|
@ -12,13 +12,6 @@ BIO_cb_post(3)
|
||||
BIO_dup_state(3)
|
||||
BIO_buffer_get_num_lines(3)
|
||||
BIO_buffer_peek(3)
|
||||
BIO_ctrl_dgram_connect(3)
|
||||
BIO_ctrl_set_connected(3)
|
||||
BIO_dgram_recv_timedout(3)
|
||||
BIO_dgram_send_timedout(3)
|
||||
BIO_dgram_get_peer(3)
|
||||
BIO_dgram_set_peer(3)
|
||||
BIO_dgram_get_mtu_overhead(3)
|
||||
BIO_sock_cleanup(3)
|
||||
ossl_bio__attr__(3)
|
||||
BN_prime_checks_for_size(3)
|
||||
|
@ -161,6 +161,13 @@ BIO_dgram_set_caps define
|
||||
BIO_dgram_get_effective_caps define
|
||||
BIO_dgram_get_mtu define
|
||||
BIO_dgram_set_mtu define
|
||||
BIO_ctrl_dgram_connect define
|
||||
BIO_ctrl_set_connected define
|
||||
BIO_dgram_get_mtu_overhead define
|
||||
BIO_dgram_get_peer define
|
||||
BIO_dgram_set_peer define
|
||||
BIO_dgram_recv_timedout define
|
||||
BIO_dgram_send_timedout define
|
||||
BIO_do_accept define
|
||||
BIO_do_connect define
|
||||
BIO_do_handshake define
|
||||
|
Loading…
x
Reference in New Issue
Block a user