Line data Source code
1 : /********************************************************************************
2 : * Copyright (c) 2026 Accenture
3 : *
4 : * This program and the accompanying materials are made available under the
5 : * terms of the Apache License Version 2.0 which is available at
6 : * https://www.apache.org/licenses/LICENSE-2.0
7 : *
8 : * SPDX-License-Identifier: Apache-2.0
9 : ********************************************************************************/
10 :
11 : #include "someip/TcpClientChannelValidator.h"
12 : #include "someip/SomeIpConstants.h"
13 : #include "someip/SomeIpMessage.h"
14 :
15 : namespace someip
16 : {
17 : namespace
18 : {
19 3 : void sendClientToServerMagicCookie(NetworkChannel& channel)
20 : {
21 3 : ::etl::span<uint8_t> const buffer = channel.getOutputBuffer();
22 3 : SomeIpMessage cookie(buffer);
23 3 : SomeIpMessage::makeClientToServerMagicCookieMessage(cookie);
24 : // intentionally drop the send result, here socket might be in any state except 'closed'. if
25 : // the connection is broken then the next time it will be in 'closed' state. if the connection
26 : // is in SYN_SENT the next time it can be 'established' which means an ACK is received otherwise
27 : // broken and then closed.
28 3 : (void)channel.send(static_cast<uint32_t>(SomeIpConstants::HEADER_LENGTH));
29 :
30 6 : return;
31 : }
32 : } // namespace
33 :
34 11 : TcpClientChannelValidator::CachedValidator::CachedValidator(TcpClientChannelValidator& validator)
35 11 : : _validator(validator), _remote(), _localPort(0U), _cachedResult(CachedResult::NO_RESULT)
36 11 : {}
37 :
38 5 : bool TcpClientChannelValidator::CachedValidator::isChannelEstablished(
39 : ::ip::IPEndpoint const& remote, uint16_t const localPort)
40 : {
41 5 : if (hasResult(remote, localPort) == false)
42 : {
43 10 : _cachedResult = _validator.isChannelEstablished(remote, localPort) == true
44 5 : ? CachedResult::POSITIVE_RESULT
45 : : CachedResult::NEGATIVE_RESULT;
46 : }
47 5 : return _cachedResult == CachedResult::POSITIVE_RESULT;
48 : }
49 :
50 6 : void TcpClientChannelValidator::CachedValidator::checkClientChannel(
51 : ::ip::IPEndpoint const& remote, uint16_t const localPort)
52 : {
53 6 : if (_validator._magicCookieEnabled == false)
54 : {
55 0 : return;
56 : }
57 6 : if (hasResult(remote, localPort) == false)
58 : {
59 4 : _validator.checkClientChannel(remote, localPort);
60 4 : _cachedResult = CachedResult::RESULT_PENDING;
61 : }
62 : }
63 :
64 11 : bool TcpClientChannelValidator::CachedValidator::hasResult(
65 : ::ip::IPEndpoint const& remote, uint16_t const localPort)
66 : {
67 : bool const res
68 3 : = ((_cachedResult != CachedResult::NO_RESULT) && (remote == _remote)
69 14 : && (localPort == _localPort));
70 11 : if (res == false)
71 : {
72 9 : _remote = remote;
73 9 : _localPort = localPort;
74 : }
75 11 : return res;
76 : }
77 :
78 72 : TcpClientChannelValidator::TcpClientChannelValidator(
79 72 : INetwork& network, bool const magicCookieEnabled)
80 72 : : _network(network), _magicCookieEnabled(magicCookieEnabled)
81 72 : {}
82 :
83 5 : bool TcpClientChannelValidator::isChannelEstablished(
84 : ::ip::IPEndpoint const& remote, uint16_t const localPort) const
85 : {
86 : ::etl::optional<NetworkChannel> channel
87 5 : = _network.getRpcChannel(localPort, remote, proto::SD_L4_PROTO_TCP);
88 :
89 10 : return (channel.has_value() && channel.value().isConnected());
90 5 : }
91 :
92 4 : void TcpClientChannelValidator::checkClientChannel(
93 : ::ip::IPEndpoint const& remote, uint16_t const localPort) const
94 : {
95 : ::etl::optional<NetworkChannel> channel
96 4 : = _network.getRpcChannel(localPort, remote, proto::SD_L4_PROTO_TCP);
97 4 : if ((channel.has_value() == false) || (channel.value().isMagicCookieEnabled() == false))
98 : {
99 1 : return;
100 : }
101 3 : sendClientToServerMagicCookie(channel.value());
102 4 : }
103 :
104 : } // namespace someip
|