blob: 3f82c9d79db08efb194e547b3d2de7fc5640f0d5 [file] [log] [blame]
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef P2P_BASE_TCP_PORT_H_
#define P2P_BASE_TCP_PORT_H_
#include <cstddef>
#include <cstdint>
#include <list>
#include <memory>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "api/candidate.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/transport/stun.h"
#include "p2p/base/connection.h"
#include "p2p/base/port.h"
#include "p2p/base/port_interface.h"
#include "p2p/base/stun_request.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/checks.h"
#include "rtc_base/containers/flat_map.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/weak_ptr.h"
namespace webrtc {
class TCPConnection;
// Communicates using a local TCP port.
//
// This class is designed to allow subclasses to take advantage of the
// connection management provided by this class. A subclass should take of all
// packet sending and preparation, but when a packet is received, it should
// call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
class TCPPort : public Port {
public:
static std::unique_ptr<TCPPort> Create(const PortParametersRef& args,
uint16_t min_port,
uint16_t max_port,
bool allow_listen) {
// Using `new` to access a non-public constructor.
return absl::WrapUnique(
new TCPPort(args, min_port, max_port, allow_listen));
}
~TCPPort() override;
Connection* CreateConnection(const Candidate& address,
CandidateOrigin origin) override;
void PrepareAddress() override;
// Options apply to accepted sockets.
// TODO(bugs.webrtc.org/13065): Apply also to outgoing and existing
// connections.
int GetOption(Socket::Option opt, int* value) override;
int SetOption(Socket::Option opt, int value) override;
int GetError() override;
bool SupportsProtocol(absl::string_view protocol) const override;
ProtocolType GetProtocol() const override;
protected:
TCPPort(const PortParametersRef& args,
uint16_t min_port,
uint16_t max_port,
bool allow_listen);
// Handles sending using the local TCP socket.
int SendTo(const void* data,
size_t size,
const SocketAddress& addr,
const AsyncSocketPacketOptions& options,
bool payload) override;
// Accepts incoming TCP connection.
void OnNewConnection(AsyncListenSocket* socket,
AsyncPacketSocket* new_socket);
private:
struct Incoming {
SocketAddress addr;
AsyncPacketSocket* socket;
};
void TryCreateServerSocket();
AsyncPacketSocket* GetIncoming(const SocketAddress& addr,
bool remove = false);
// Receives packet signal from the local TCP Socket.
void OnReadPacket(AsyncPacketSocket* socket, const ReceivedIpPacket& packet);
void OnSentPacket(AsyncPacketSocket* socket,
const SentPacketInfo& sent_packet) override;
void OnReadyToSend(AsyncPacketSocket* socket);
bool allow_listen_;
std::unique_ptr<AsyncListenSocket> listen_socket_;
// Options to be applied to accepted sockets.
// TODO(bugs.webrtc:13065): Configure connect/accept in the same way, but
// currently, setting OPT_NODELAY for client sockets is done (unconditionally)
// by BasicPacketSocketFactory::CreateClientTcpSocket.
flat_map<Socket::Option, int> socket_options_;
int error_;
std::list<Incoming> incoming_;
friend class TCPConnection;
};
class TCPConnection : public Connection, public sigslot::has_slots<> {
public:
// Connection is outgoing unless socket is specified
TCPConnection(WeakPtr<Port> tcp_port,
const Candidate& candidate,
AsyncPacketSocket* socket = nullptr);
~TCPConnection() override;
int Send(const void* data,
size_t size,
const AsyncSocketPacketOptions& options) override;
int GetError() override;
AsyncPacketSocket* socket() { return socket_.get(); }
// Allow test cases to overwrite the default timeout period.
int reconnection_timeout() const { return reconnection_timeout_; }
void set_reconnection_timeout(int timeout_in_ms) {
reconnection_timeout_ = timeout_in_ms;
}
protected:
// Set waiting_for_stun_binding_complete_ to false to allow data packets in
// addition to what Port::OnConnectionRequestResponse does.
void OnConnectionRequestResponse(StunRequest* req,
StunMessage* response) override;
private:
friend class TCPPort; // For `MaybeReconnect()`.
// Helper function to handle the case when Ping or Send fails with error
// related to socket close.
void MaybeReconnect();
void CreateOutgoingTcpSocket() RTC_RUN_ON(network_thread());
void ConnectSocketSignals(AsyncPacketSocket* socket)
RTC_RUN_ON(network_thread());
void DisconnectSocketSignals(AsyncPacketSocket* socket)
RTC_RUN_ON(network_thread());
void OnConnect(AsyncPacketSocket* socket);
void OnClose(AsyncPacketSocket* socket, int error);
void OnSentPacket(AsyncPacketSocket* socket,
const SentPacketInfo& sent_packet);
void OnReadPacket(AsyncPacketSocket* socket, const ReceivedIpPacket& packet);
void OnReadyToSend(AsyncPacketSocket* socket);
void OnDestroyed(Connection* c);
TCPPort* tcp_port() {
RTC_DCHECK_EQ(port()->GetProtocol(), webrtc::PROTO_TCP);
return static_cast<TCPPort*>(port());
}
std::unique_ptr<AsyncPacketSocket> socket_;
int error_;
const bool outgoing_;
// Guard against multiple outgoing tcp connection during a reconnect.
bool connection_pending_;
// Guard against data packets sent when we reconnect a TCP connection. During
// reconnecting, when a new tcp connection has being made, we can't send data
// packets out until the STUN binding is completed (i.e. the write state is
// set to WRITABLE again by Connection::OnConnectionRequestResponse). IPC
// socket, when receiving data packets before that, will trigger OnError which
// will terminate the newly created connection.
bool pretending_to_be_writable_;
// Allow test case to overwrite the default timeout period.
int reconnection_timeout_;
ScopedTaskSafety network_safety_;
};
} // namespace webrtc
// Re-export symbols from the webrtc namespace for backwards compatibility.
// TODO(bugs.webrtc.org/4222596): Remove once all references are updated.
#ifdef WEBRTC_ALLOW_DEPRECATED_NAMESPACES
namespace cricket {
using ::webrtc::TCPConnection;
using ::webrtc::TCPPort;
} // namespace cricket
#endif // WEBRTC_ALLOW_DEPRECATED_NAMESPACES
#endif // P2P_BASE_TCP_PORT_H_