Commit Graph

98 Commits

Author SHA1 Message Date
Pau Espin 3e6f4d12c9 stream: Document osmo_stream_srv_recv() SCTP specialties
Change-Id: I47b066f26e63afd4bdb135f822667d1cd9479920
2022-09-30 17:57:56 +02:00
Pau Espin 96271688cf stream: Return 0 when receiving sctp notification SCTP_COMM_LOST
It was seen on a real pcap trace (sctp & gsmtap_log) that the Linux
kernel stack may decide to kill the connection (sending an ABORT) if
it fails to transmit some data after a while:
ABORT Cause code: "Protocol violation (0x000d)",
      Cause Information: "Association exceeded its max_retrans count".
When this occurs, the kernel sends the
MSG_NOTIFICATION,SCTP_ASSOC_CHANGE,SCTP_COMM_LOST notification when
reading from the socket with sctp_recvmsg(). This basically signals that
the socket conn is dead, and subsequent writes to it will result in
send() failures (and receive SCTP_SEND_FAILED notification upon follow
up reads).
It's important to notice that after those events, there's no other sort
of different event like SHUTDOWN coming in, so that's the time at which
we must tell the user to close the socket.
Hence, let's signal the caller that the socket is dead by returning 0,
to comply with usual recv() API.

Related: SYS#6113
Change-Id: If94d44f25b76a96a5ea402fec9fc14c4e6296ba3
2022-09-30 17:57:40 +02:00
Pau Espin 04572b2f6a stream: Remove unneeded break statement
Change-Id: Iaa36a3661fc3d049f656342ee6dc3aafd45498bb
2022-09-30 14:24:12 +02:00
Pau Espin 8dd1e15661 stream: Set sctp_ppid and sctp_stream when sctp notifciation is received
Let's set these values in all cases.

Change-Id: I99f6098d8d9fc1c06bc28373bf7ee76f15d5f525
2022-09-30 14:22:15 +02:00
Pau Espin 36a9f3eae8 stream: Log rx of sctp notification SCTP_SEND_FAILED
Change-Id: I16d3ed950d4da3b13cca25bcd8f29af0d880c23e
2022-09-30 14:21:22 +02:00
Pau Espin 5dd81f3c63 stream: Erase sctp_msg_flags if receiving user data
It could be that the user reuses the msgb passed to
osmo_stream_srv_recv() all the time, hence we need to reset the flags,
otherwise it may end up being set forever.

Change-Id: Id358140db82b018e3973111e530834589c0b7224
2022-09-30 14:09:34 +02:00
Pau Espin 56f20d4192 stream: Set proper msgb length when returning sctp_notification
This allows the user to properly check the size of the content in case
the struct ABI changes.
-EAGAIN is still returned to avoid older users of the API reading SCTP
notifications as user data.

Change-Id: I95e2457498fd8e0d790d221cb97695ace0dd673e
2022-09-30 14:07:03 +02:00
Pau Espin 668c804197 stream: Provide caller with SCTP flags during osmo_stream_*_recv()
The user may want to check the flags in order to know if the content
pointed at by msgb is an sctp_notification structure, and not in-band
data.
This is useful for the user in order to gain connection state such as
SCTP RESET notification, which means the client reconnected reusing the
same socket, loosing all higher layers state.

The MSG_NOTIFICATION from netinet/sctp.h is not reused, and instead an
osmocom specific flag (and bitmask) is used. This is done in order to
fit the flags in one byte, since for instance MSG_NOTIFICATION requires
2 bytes in my system (0x8000).

Related: SYS#6113
Change-Id: I0ee94846a15a23950b9d70eaaef1251267296bdd
2022-09-19 14:50:34 +02:00
Pau Espin 98c75ef273 stream: Unset fd value after close() before calling closed_cb()
The fd is not valid anymore after close() call, so let's set it to a
clearly invalid value, to avoid confusion on closed_cb() users
attempting to use the fd get info about the socket at that time.

Change-Id: I82d9bdfb38cf5e9f689eca0d9a4c19ddd5541af7
2022-09-13 12:47:33 +02:00
Pau Espin 2087d61c21 stream: Fix typos in log messages
Change-Id: I9e49e222c254c89d182402501024badfd3bf9d9c
2022-09-12 12:44:03 +02:00
Max a69baa9184 Properly handle send() return code
Change-Id: If9b80e855b740254d5414ea50b4ce594855da8e9
2022-08-21 21:46:46 +07:00
Max f7bea130e6 Log more details in osmo_stream_srv_write()
Log error code and amount of data:
both are handy for debugging apps using the library.

Change-Id: I580c00f3b5ade05ecb20a92ce4ece2854334a41f
2022-08-21 20:01:50 +07:00
Pau Espin dcae6dd99d stream: getsockopt ret socklen_t is unsigned
Found out by following gcc warning:
"""
libosmo-netif/src/stream.c:147:11: warning: argument to variable-length array may be too large due to conversion from ‘int’ to ‘unsigned int’ [-Wvla-larger-than=]
  147 |   uint8_t buf[sctp_sockopt_event_subscribe_size];
      |           ^~~
"""

Change-Id: I181ae5c0480788fc96abd2bb1edf003244884c8f
2022-07-18 18:18:16 +02:00
Pau Espin 0f067d8809 stream: assert params are not NULL in send/recv functions
Change-Id: Ie9e67396973128aba87b584be1a36e2a94dd0998
2022-07-05 18:26:53 +02:00
Pau Espin b2b5f1c6bf stream: Add support for AF_UNIX sockets
Change-Id: I5237a8121be05a9a31a39ca38a6a139062f258c4
2021-12-09 13:47:41 +01:00
Pau Espin 4cf31f187a stream: Factor out sctp_recvmg long code chunk
This makes it easier to follow the general path selection based on
protocol type. It will also make it easier when we add new paths based
on socket domain.

Change-Id: Ia3e0f4407e00a2dac9ee885fe1cc1cb4b463898a
2021-12-01 14:52:47 +01:00
Harald Welte 637025b2f7 migrate to osmo_fd_{read,write}_{enable,disable}()
Change-Id: Ia8ffcbc61883a4e1615c101dbd3307771ae33974
Depends: libosmocore.git Change-Id Idb89ba7bc7c129a6304a76900d17f47daf54d17d
2021-02-11 15:40:54 +01:00
Harald Welte bd775e4adb cosmetic: Fix whitespace (use tab instead of 8x space)
Change-Id: I2b8d80fb771336d4d2c4a9ea1749935bdf14a37b
2020-10-21 14:03:29 +02:00
Harald Welte eb96eb7d68 Use osmo_fd_setup() wherever applicable
Change-Id: Ifb90e00036cc51ef02f3cf4dda1ff7dcd1f8a5b5
2020-10-18 23:12:20 +02:00
Vadim Yanitskiy a38b83f395 stream: add missing Doxygen \return statements to non-void functions
Change-Id: I693939946497ad08f45cab238a56ceee29578056
2020-09-02 11:39:19 +07:00
Pau Espin 97a293e46a stream: Fix log of IPv6 during accept()
Change-Id: Ib13db8d135138059a70d18a8bba14e53c6514fa7
2020-08-24 12:05:30 +02:00
Pau Espin ef6ae62c6e stream: Support creating sockets with IPv6 addresses
In the case of SCTP, an association supports now containing both IPv4
and v6 addresses.

Depends: libosmocore.git Change-Id I36d8ab85d92bba4d6adb83bc1875eb61094ed2ef
Change-Id: Ie6bb17a9af6ca21d5e350f9c9d2d74c97c5a00af
2020-08-19 18:15:38 +02:00
Pau Espin b1e01cbbbd stream: Fix some SCTP code not disabled if --disable-libsctp is used
Some previous commit added some code to workaround some kernel ABI
unstabilities but forgot to add the code inside a conditional
preprocessor block.

Fixes: 157ad6d707
Change-Id: Ibee01222d8d11cf2520cdbd4d0d5bed6b72d2107
2020-07-06 12:36:18 +02:00
Harald Welte 77a856878f src/stream.c: Don't leak socket during SCTP_EVENTS getsockopt
In Commit Icc49f347cdc0bb77a5c0e230597d662ac35b4acc I forgot to
close the socket :/

Change-Id: I384c61dac0eac8ad999ff0d62350c2fcf3e57ea9
2020-06-03 10:32:27 +02:00
Harald Welte 157ad6d707 src/stream: Work around more Linux kernel ABI breakage
Back in Change-Id Ia95dd1f9ffed9f743c049e05797b1a6f1f9f8c69 we tried
to work-around kernel ABI breakage introduced in kernel >= v5.5, but it
seems that there have already been similar ABI breakages in v4.11 and v4.12.

See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/uapi/linux/sctp.h?id=b6e6b5f1da7e8d092f86a4351802c27c0170c5a5
and https://marc.info/?l=linux-sctp&m=158729301516157&w=2 for the most
recent incarnation.

See https://osmocom.org/issues/4573#note-6 for all known cases
of SCTP_EVENTS ABI breakage.

Closes: OS#4573
Change-Id: Icc49f347cdc0bb77a5c0e230597d662ac35b4acc
2020-06-02 20:54:05 +00:00
Pau Espin b988f2bb36 Use OSMO_FD_* instead of deprecated BSC_FD_*
New define is available since libosmocore 1.1.0, and we already require
1.3.0, so no need to update dependenices.
Let's change it to avoid people re-using old BSC_FD_* symbols when
copy-pasting somewhere else.

Change-Id: I269690c1c9e4d19b5b69eef206b95e71f7931188
2020-05-09 19:14:17 +02:00
Sylvain Munaut 141b64f25b stream: Attempt to workaround kernel ABI breakage
See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/uapi/linux/sctp.h?id=b6e6b5f1da7e8d092f86a4351802c27c0170c5a5
and https://marc.info/?l=linux-sctp&m=158729301516157&w=2

A kernel structure changed size, a new field was added at the end.
Attempt to submit with the known "old" size.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Change-Id: Ia95dd1f9ffed9f743c049e05797b1a6f1f9f8c69
2020-05-08 13:42:51 +02:00
Pau Espin 97c3226e90 stream: Rename cli state NONE to CLOSED
It makes a lot more sense calling it this way since it matches the state
of the stream at that point.

Change-Id: Ic02aec3f7f095e0e0e1f940425f577be5048e98f
2020-01-28 13:19:53 +01:00
Pau Espin 7f8e0502e2 stream: Add new WAIT_RECONNECT cli state
It's not really needed right now from logic point of view, since we
reused NONE for that. But it makes logging and logic clearer, and will
make it easier if we decide to move it to FSMs at a later point in time.

Other state value_string names are also modified with its whitespace
removed since anyway we'd need to change them to match WAIT_RECONNECT
length. Let's drop the space because imho it's not that useful and
anyway if we move to FSMs at some point then we won't have them anyway.

Change-Id: I7b9a6da87081c418b0d14bab5f34369c5eca6fe8
2020-01-28 13:18:36 +01:00
Pau Espin 6326e8ff85 stream: Re-arrange cli states to fix 100% cpu usage bug
With previous state, osmo_stream_cli_close() could be called from
osmo_stream_cli_open()(), and in that case state was kept as NONE while
ending up with an associated fd being registered in the select loop.
As a result, osmo_stream_cli_fd_cb() could be called while in state
NONE, which was not expected and would simply return without modifying
fd state flags, causing it to be called again and again.

Related: OS#4378
Change-Id: Ie3342f882893a71ad1538c17ad9ee9fa4433eaa4
2020-01-28 12:50:31 +01:00
Pau Espin 3fc969e3d6 stream: Drop data during write() while in state NONE
It should not happen anyway because no fd should be active if state is
NONE, but still it's an extra check.

Change-Id: I6d58762b7d10078eb8d0981c13d35cb6f85cfe86
2020-01-28 12:30:24 +01:00
Pau Espin 5ed1a3c85c stream.c: Improve logging during sock send()
Change-Id: Iff275c809ec2bb34f471d15bfdc92296566b76a7
2020-01-09 20:38:05 +01:00
Pau Espin d1b1ff77a6 configure.ac: Introduce --{enable,disable}-libsctp configure flag
Similar to what we do in libosmocore already, we want to
deterministically enable or disable support for the feature without
having into account if the system has a libsctp. If libsctp is missing
and support is enabled, then fail.

Extra checks are also added:
* Check netinet/sctp.h header
* Check libosmocore was built with libsctp support (API
osmo_sock_init2_multiaddr() we require).
* In stream.c make sure it can be built without HAVE_LIBSCTP, and that
set_addrs() fails for more than 1 address (since that feature is only
supported through osmo_sock_init2_multiaddrs()).

Change-Id: I4b3e1f1894f13ac1175a71a5139c02a2633be26d
2020-01-09 14:10:20 +01:00
Pau Espin ee5c860268 stream: Fix fd param passed to close() in error conditon
Fixes: CID#205089, CID#205087
Change-Id: I65714f214b9962862cda01605c7c2c578c78d3c7
2019-10-21 11:27:36 +02:00
Pau Espin c3a6c75cea stream: osmo_stream_cli: Support setting multiple addr
This API will be later used to set multiple addresses for SCTP sockets.

Depends: libosmocore.git Ic8681d9e093216c99c6bca4be81c31ef83688ed1
Related: OS#3608

Change-Id: I09f0d989f2309abdeb304fe570355abed2cd107b
2019-10-15 13:11:54 +02:00
Pau Espin f254ef80f2 stream: osmo_stream_srv_link: Support setting multiple addr
This API will be later used to set multiple addresses for SCTP sockets.

Depends: libosmocore.git Ic8681d9e093216c99c6bca4be81c31ef83688ed1
Related: OS#3608
Change-Id: I0fe62f518e195db4e34f3b0ad1762bb57ba9d92a
2019-10-15 13:11:51 +02:00
Pau Espin c25285f40e stream.c: remove duplicated line setting variable
Change-Id: I03b05179f5656ab81e5e14cd146f82a471f7b071
2019-10-10 12:26:30 +02:00
Pau Espin a1e9de1ec4 stream: Fix scheduling of queued messages during connecting state
If messages are sent using osmo_stream_cli_send() while the stream
is still (re)connecting, they won't have a chance to be sent until the
stream is connected, and hence they are queued until
CONNECTING->CONNECTED is done. However, at that time
(osmo_stream_cli_fd_cb), the WRITE flag was dropped unconditionally,
which meant already queued packets didn't have the opportunity to be
sent by the same callback until first message is enqueued and WRITE flag
is set (again by osmo_stream_cli_send()).
Let's make them be sent as soon as possible once the connection is
available.

Related: OS#4188
Change-Id: I289495f9aad6389c5f2623fb072d676235b7d24c
2019-09-04 17:40:22 +02:00
Pau Espin 962bf9a48e stream: Introduce API osmo_stream_cli_is_connected
Can be used by users to fetch current status of the stream.

Change-Id: I5402430e5f39eef22dfa18f33807ab6b1e771f1b
2019-09-04 17:04:18 +02:00
Max b3e34435b3 Deprecate osmo_stream_cli_open2()
This supposed to be variant of osmo_stream_cli_open() with explicit
control over reconnection logic but it's plain broken: doxygen docs
contradict the code, actual reconnection logic is affected by timeout
parameter directly which is set in different function.

It seems like we haven't been affected by this so far because we always
use it in auto-reconnection mode which is triggered by default due to
positive reconnection timeout value (5 sec) automatically used in the
absense of explicitly set timeout.

Looking at commit history, this function already been source of
confusion in the past. Instead of trying to fix this mess, let's just
deprecate it entirely and properly document use of
osmo_stream_cli_set_reconnect_timeout() to control reconnection logic.

The only known user is libosmo-sccp which won't use it as of
0a93a683f3cb8e5977eb4a666ab207db6e7d7af9 commit.

Change-Id: Id988ed0274b363db049f59cbf6a193727c8c3c8a
2019-03-19 13:40:55 +00:00
Max af63d87a76 Stream client: add disconnect callback
It's similar to connect_cb() but called once client has been
disconnected.

Change-Id: I905adb2d6191216551a3bcdcd1aec1f96f01612a
2019-02-20 17:33:32 +01:00
Max 1a357720b5 Stream client: report reconnection event as INFO
This helps to avoid unnecessary debug output in reconnection logic tests
in follow-up patches.

Change-Id: Ic96430a9e9294e72de23b0bbacdbf3e99a453f1d
2019-02-07 13:38:22 +01:00
Max 827d693b50 Stream client: fix disconnection logic
Previously closing the client did not alter its state, so we might
end-up with a client without any file descriptors, but being in state
STREAM_CLI_STATE_CONNECTED. Fix this inconsistency by setting
appropriate state.

Related issue is that reconnect function, which is always (at least in
the library and examples) called when some problem with the connection
is detected, closed the connection only after checking whether
reconnection is enabled. This might result in another inconsistency
fixed in this patch by moving the check below connection cleanup.

While at it, also move connection close logging to appropriate place:
it's confusing to see logs about connection being closed while in
reality it wasn't even established.

Change-Id: If41ed60bd625488c283d1e8a2b078e640f04c78e
2019-02-05 16:26:49 +00:00
Max 732652b5b7 Add socket name functions to stream client/server
Add functions to get the description of a server link or client
connection which examine data on corresponding socket.

Those functions use static buffers and intended for single use in
log/printf statements as illustarted by corresponding example changes.

Change-Id: If9a8e211da85956781479862a63c4fc6e53ed6be
2019-02-05 16:25:20 +00:00
Max a93bb2ca34 Stream client: update logging
Introduce logging macro wrapper to properly log current client state and
function to aid in debugging.

Change-Id: Ie22a80dcec95998cce0b25053fdf74f23eab6e53
2019-02-05 16:21:26 +00:00
Max e3366cf144 Stream client: fix doxygen typo
Change-Id: Ic45d3e0520db4060c5c24e5ef5a766a52f060a34
2019-02-04 13:23:27 +01:00
Neels Hofmeyr dc8fcf5a69 logging: fix typo in stream.c
Change-Id: I5dcae1f19e18f04709ce7585943af1d582ebc7ed
2018-12-10 13:11:41 +01:00
Stefan Sperling a555a1fca2 detect freed connections in osmo_stream_srv_read()
While we are processing a read event, the connection's
callback might free the connection. Check for this and don't
attempt to process further events on an already freed connection.

Change-Id: I0a9c7d8e3263c73440f7084dbb1792a4ca5038f0
Related: OS#3685
Depends: g#11704 (for libosmo-sccp)
2018-11-09 15:33:19 +01:00
Harald Welte ac33f6fbd2 stream.c: Use non-blocking connect in osmo_stream_cli
When establishing a client-side stream connection via libosmo-netif,
we must using non-blocking connect if we want to avoid blocking/stalling
the entire process.  The libosmocore socket API provides the
OSMO_SOCK_F_NONBLOCK flag for this.  Make use of it!

Change-Id: I9bfcb39b5801a36ef32ca0d1f3eb8236687d7ed6
Related: OS#3383
2018-07-05 14:07:25 +02:00
Pau Espin c71c9516dd stream.c: osmo_stream_cli_open2: Remove wrong assumption in reconnect decision
Documentation of osmo_sock_init2 doesn't provide information of any
specific value of errno set/expected after running the function. It is
incorrect to expect a specific value of errno and looking at the
implementation it is actually not a good idea to check it.

If reconnect flag is set, let's reconnect always instead of looking at
errno to decide.

Change-Id: I25b33f4cdc496ae31ff240d445b9b2805091845c
2018-04-05 18:07:41 +02:00