1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef SERVICES_NETWORK_P2P_SOCKET_UDP_H_
6 #define SERVICES_NETWORK_P2P_SOCKET_UDP_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <set>
13 #include <vector>
14 
15 #include "base/callback.h"
16 #include "base/compiler_specific.h"
17 #include "base/component_export.h"
18 #include "base/containers/circular_deque.h"
19 #include "base/macros.h"
20 #include "base/memory/ref_counted.h"
21 #include "mojo/public/cpp/bindings/pending_receiver.h"
22 #include "mojo/public/cpp/bindings/pending_remote.h"
23 #include "net/base/ip_endpoint.h"
24 #include "net/socket/diff_serv_code_point.h"
25 #include "net/socket/udp_server_socket.h"
26 #include "net/traffic_annotation/network_traffic_annotation.h"
27 #include "services/network/p2p/socket.h"
28 #include "services/network/public/cpp/p2p_socket_type.h"
29 #include "third_party/webrtc/rtc_base/async_packet_socket.h"
30 
31 namespace net {
32 class NetLog;
33 }  // namespace net
34 
35 namespace network {
36 
37 class P2PMessageThrottler;
38 
COMPONENT_EXPORT(NETWORK_SERVICE)39 class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocketUdp : public P2PSocket {
40  public:
41   using DatagramServerSocketFactory =
42       base::RepeatingCallback<std::unique_ptr<net::DatagramServerSocket>(
43           net::NetLog* net_log)>;
44   P2PSocketUdp(Delegate* delegate,
45                mojo::PendingRemote<mojom::P2PSocketClient> client,
46                mojo::PendingReceiver<mojom::P2PSocket> socket,
47                P2PMessageThrottler* throttler,
48                net::NetLog* net_log,
49                const DatagramServerSocketFactory& socket_factory);
50   P2PSocketUdp(Delegate* delegate,
51                mojo::PendingRemote<mojom::P2PSocketClient> client,
52                mojo::PendingReceiver<mojom::P2PSocket> socket,
53                P2PMessageThrottler* throttler,
54                net::NetLog* net_log);
55   ~P2PSocketUdp() override;
56 
57   // P2PSocket overrides.
58   void Init(const net::IPEndPoint& local_address,
59             uint16_t min_port,
60             uint16_t max_port,
61             const P2PHostAndIPEndPoint& remote_address,
62             const net::NetworkIsolationKey& network_isolation_key) override;
63 
64   // mojom::P2PSocket implementation:
65   void Send(const std::vector<int8_t>& data,
66             const P2PPacketInfo& packet_info,
67             const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
68       override;
69   void SetOption(P2PSocketOption option, int32_t value) override;
70 
71  private:
72   friend class P2PSocketUdpTest;
73 
74   typedef std::set<net::IPEndPoint> ConnectedPeerSet;
75 
76   struct PendingPacket {
77     PendingPacket(const net::IPEndPoint& to,
78                   const std::vector<int8_t>& content,
79                   const rtc::PacketOptions& options,
80                   uint64_t id,
81                   const net::NetworkTrafficAnnotationTag traffic_annotation);
82     PendingPacket(const PendingPacket& other);
83     ~PendingPacket();
84     net::IPEndPoint to;
85     scoped_refptr<net::IOBuffer> data;
86     int size;
87     rtc::PacketOptions packet_options;
88     uint64_t id;
89     const net::NetworkTrafficAnnotationTag traffic_annotation;
90   };
91 
92   void DoRead();
93   void OnRecv(int result);
94 
95   // Following 3 methods return false if the result was an error and the socket
96   // was destroyed. The caller should stop using |this| in that case.
97   WARN_UNUSED_RESULT bool HandleReadResult(int result);
98   WARN_UNUSED_RESULT bool HandleSendResult(uint64_t packet_id,
99                                            int32_t transport_sequence_number,
100                                            int64_t send_time_ms,
101                                            int result);
102   WARN_UNUSED_RESULT bool DoSend(const PendingPacket& packet);
103 
104   void OnSend(uint64_t packet_id,
105               int32_t transport_sequence_number,
106               int64_t send_time_ms,
107               int result);
108 
109   int SetSocketDiffServCodePointInternal(net::DiffServCodePoint dscp);
110 
111   std::unique_ptr<net::DatagramServerSocket> socket_;
112   scoped_refptr<net::IOBuffer> recv_buffer_;
113   net::IPEndPoint recv_address_;
114 
115   base::circular_deque<PendingPacket> send_queue_;
116   bool send_pending_ = false;
117   net::DiffServCodePoint last_dscp_ = net::DSCP_CS0;
118 
119   // Set of peer for which we have received STUN binding request or
120   // response or relay allocation request or response.
121   ConnectedPeerSet connected_peers_;
122   P2PMessageThrottler* throttler_;
123 
124   net::NetLog* net_log_;
125 
126   // Callback object that returns a new socket when invoked.
127   DatagramServerSocketFactory socket_factory_;
128 
129   DISALLOW_COPY_AND_ASSIGN(P2PSocketUdp);
130 };
131 
132 }  // namespace network
133 
134 #endif  // SERVICES_NETWORK_P2P_SOCKET_UDP_H_
135