Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG/TEST] Refaxed and fixed multiplexer reusage. Fixed ReuseAddr tests. #2608

Merged
merged 24 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1cfe0e5
Refaxed and fixed multiplexer reusage. Fixed ReuseAddr tests.
Jan 11, 2023
8b4352c
Small fix for an unlikely case of accepting from a closed listener
Jan 11, 2023
5c5d2dc
Withdrawn resetting sync before closing - useless and not always work…
Jan 11, 2023
6644c75
Fixed mux reusage for IPv6. Added IPv6 SameAddr test. Fixed not setti…
Jan 12, 2023
adfda78
Fixed: local IP filtering as default local addr not always must be IP…
Jan 12, 2023
3ba87f9
Updated documentation. Added trial fix to reject undefined V6ONLY whe…
Jan 13, 2023
066a4d8
Fixed problematic CMSG handling in case of IPv4+IPv6 and mapped IPv4
Jan 16, 2023
b855a30
Changed threads to futures to allow for assertions in threads
Jan 16, 2023
5aea54f
Removed unused constant that caused failure on Windows
Jan 16, 2023
200e7c1
Fixed for systems with weird msg flags definitions
Jan 17, 2023
ef64980
Improved test marks to better identify tests to be excluded on CI pla…
Jan 17, 2023
abe939e
Enforced async policy for async call to prevent spawning caller too late
Jan 17, 2023
18db3c8
Enabled check if SRTO_IPV6ONLY option is set before omni binding in I…
Jan 25, 2023
6edddf3
Merge branch 'master' into dev-fix-reuseaddr-test
Jan 25, 2023
a3fb814
Cleaned up markers and unused code
Jan 25, 2023
d777686
Fixed some simple errors reported by the reviewer
ethouris Jan 26, 2023
d439a9d
Merge branch 'master' into dev-fix-reuseaddr-test
Jan 27, 2023
278fbfc
Changed muxer config operator== into a function (partial followup)
Jan 31, 2023
1ab4477
Apply doc suggestions from code review
ethouris Feb 1, 2023
1d2aa1d
Added bind collision table
ethouris Feb 1, 2023
aee8e5a
Apply suggestions from code review
maxsharabayko Feb 1, 2023
68c0d20
Apply suggestions from code review
ethouris Feb 1, 2023
0594299
Fixed naming for inet6settings
Feb 1, 2023
61f2400
Followup for doc fixes
ethouris Feb 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ matrix:
- BUILD_TYPE=Release
- BUILD_OPTS='-DENABLE_MONOTONIC_CLOCK=ON'
script:
- TESTS_IPv6="TestMuxer.IPv4_and_IPv6:TestIPv6.v6_calls_v6*:ReuseAddr.ProtocolVersion" ; # Tests to skip due to lack of IPv6 support
- TESTS_IPv6="TestMuxer.IPv4_and_IPv6:TestIPv6.v6_calls_v6*:ReuseAddr.ProtocolVersion:ReuseAddr.*6" ; # Tests to skip due to lack of IPv6 support
- if [ "$TRAVIS_COMPILER" == "x86_64-w64-mingw32-g++" ]; then
export CC="x86_64-w64-mingw32-gcc";
export CXX="x86_64-w64-mingw32-g++";
Expand Down
86 changes: 72 additions & 14 deletions docs/API/API-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,27 +358,84 @@ int srt_bind(SRTSOCKET u, const struct sockaddr* name, int namelen);

Binds a socket to a local address and port. Binding specifies the local network
interface and the UDP port number to be used for the socket. When the local
address is a form of `INADDR_ANY`, then it's bound to all interfaces. When the
port number is 0, then the port number will be system-allocated if necessary.
address is a wildcard (`INADDR_ANY` for IPv4 or `in6addr_any` for IPv6), then
it's bound to all interfaces (although see `SRTO_IPV6ONLY` and additional
information below for details about the wildcard address in IPv6).

Binding is necessary for every socket to be used for communication. If the socket
is to be used to initiate a connection to a listener socket, which can be done,
for example, by the [`srt_connect`](#srt_connect) function, the socket is bound
implicitly to the wildcard address according to the IP family (`INADDR_ANY` for
`AF_INET` or `in6addr_any` for `AF_INET6`) and port number 0. In all other cases,
a socket must be bound explicitly by using the functionality of this function first.

When the port number parameter is 0, then the effective port number will be
system-allocated. To obtain this effective port number you can use
[`srt_getsockname`](#srt_getsockname).

This call is obligatory for a listening socket before calling [`srt_listen`](#srt_listen)
and for rendezvous mode before calling [`srt_connect`](#srt_connect); otherwise it's
optional. For a listening socket it defines the network interface and the port where
the listener should expect a call request. In the case of rendezvous mode (when the
socket has set [`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) to
true both parties connect to one another) it defines the network interface and port
from which packets will be sent to the peer, and the port to which the peer is
expected to send packets.

For a connecting socket this call can set up the outgoing port to be used in the
communication. It is allowed that multiple SRT sockets share one local outgoing
port, as long as [`SRTO_REUSEADDR`](API-socket-options.md#SRTO_REUSEADDRS)
is set to *true* (default). Without this call the port will be automatically
selected by the system.
the listener should expect a call request.

In the case of rendezvous mode there are two parties that connect to one another.
For every party there must be chosen a local binding endpoint (local address and port)
to which they expect connection from the peer. Let's say, we have a Party 1
that selects an endpoint A and a Party 2 that selects an endpoint B. In this case the Party 1
binds the socket to the endpoint A and then connects to the endpoint B, and the Party 2
the other way around. Both sockets must be set
[`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) to *true* to make
this connection possible.

For a connecting socket the call to `srt_bind` is optional, but can be used to set up the
outgoing port for communication as well as the local interface through which
it should reach out to the remote endpoint, should that be necessary.

Whether binding is possible depends on some runtime conditions, in particular:

* No socket in the system has been bound to this port ("free binding"), or

* A socket bound to this port is bound to a certain address, and this binding is
using a different non-wildcard address ("side binding"), or

* A socket bound to this port is bound to a wildcard address for a different IP
version than the version requested for this binding ("side wildcard binding",
see also `SRTO_IPV6ONLY` socket option).

It is also possible to bind to the already busy port as long as the existing
binding ("shared binding") is possessed by an SRT socket created in the same
application, and:

* Its binding address and UDP-related socket options match the socket to be bound.
* Its [`SRTO_REUSEADDR`](API-socket-options.md#SRTO_REUSEADDRS) is set to *true* (default).

If none of the free, side and shared binding options is currently possible, this function
will fail. If the socket blocking the requested endpoint is an SRT
socket in the current application, it will report the `SRT_EBINDCONFLICT` error,
while if it was another socket in the system, or the problem was in the system
in general, it will report `SRT_ESOCKFAIL`. Here is the table that shows possible situations:

| Address in srt_bind | Result for attempted binding | | | | |
|---------------------|------------------------------|-----------|-----------------------------|---------------|---------------|
| Bind address | A.B.C.D | 0.0.0.0 | ::X | :: / V6ONLY=1 | :: / V6ONLY=0 |
| 1.2.3.4 | 1.2.3.4 shareable, else free | blocked | free | free | blocked |
| 0.0.0.0 | blocked | shareable | free | free | blocked |
| 8080::1 | free | free | 8080::1 sharable, else free | blocked | blocked |
| :: / V6ONLY=1 | free | free | blocked | sharable | blocked |
| :: / V6ONLY=0 | blocked | blocked | blocked | blocked | sharable |


**NOTE**: This function cannot be called on a socket group. If you need to
have the group-member socket bound to the specified source address before
connecting, use [`srt_connect_bind`](#srt_connect_bind) for that purpose.
connecting, use [`srt_connect_bind`](#srt_connect_bind) for that purpose
or set the appropriate source address using
[`srt_prepare_endpoint`](#srt_prepare_endpoint).

**IMPORTANT information about IPv6**: If you are going to bind to the
`in6addr_any` IPv6 wildcard address (known as `::`), the `SRTO_IPV6ONLY`
option must be first set explicitly to 0 or 1, otherwise the binding
will fail. In all other cases this option is meaningless. See `SRTO_IPV6ONLY`
option for more information.

| Returns | |
|:----------------------------- |:--------------------------------------------------------- |
Expand All @@ -389,6 +446,7 @@ connecting, use [`srt_connect_bind`](#srt_connect_bind) for that purpose.
|:---------------------------------------- |:-------------------------------------------------------------------- |
| [`SRT_EINVSOCK`](#srt_einvsock) | Socket passed as [`u`](#u) designates no valid socket |
| [`SRT_EINVOP`](#srt_einvop) | Socket already bound |
| [`SRT_EINVPARAM`](#srt_einvparam) | Invalid `name`/`namelen` or invalid `SRTO_IPV6ONLY` flag in `u` |
| [`SRT_ECONNSETUP`](#srt_econnsetup) | Internal creation of a UDP socket failed |
| [`SRT_ESOCKFAIL`](#srt_esockfail) | Internal configuration of a UDP socket (`bind`, `setsockopt`) failed |
| [`SRT_EBINDCONFLICT`](#srt_ebindconflict)| Binding specification conflicts with existing one |
Expand Down
15 changes: 11 additions & 4 deletions docs/API/API-socket-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,17 @@ and the actual value for connected sockets.
| ---------------- | ----- | -------- | ---------- | ------ | -------- | ------ | --- | ------ |
| `SRTO_IPV6ONLY` | 1.4.0 | pre-bind | `int32_t` | | (system) | -1..1 | RW | GSD |

Set system socket flag `IPV6_V6ONLY`. When set to 0 a listening socket binding an
IPv6 address accepts also IPv4 clients (their addresses will be formatted as
IPv4-mapped IPv6 addresses). By default (-1) this option is not set and the
platform default value is used.
Set system socket option level `IPPROTO_IPV6` named `IPV6_V6ONLY`. This is meaningful
only when the socket is going to be bound to the IPv6 wildcard address `in6addr_any`
(known also as `::`). In this case this option must be also set explicitly to 0 or 1
before binding, otherwise binding will fail (this is because it is not possible to
determine the default value of this above-mentioned system option in any portable or
reliable way). Possible values are:

* -1: (default) use system-default value (can be used when not binding to IPv6 wildcard `::`)
* 0: The binding to `in6addr_any` will bind to both IPv6 and IPv4 wildcard address
* 1: The binding to `in6addr_any` will bind only to IPv6 and not IPv4 wildcard address


[Return to list](#list-of-options)

Expand Down
Loading