summaryrefslogtreecommitdiffstats
path: root/mojo/services/network/udp_socket_impl.h
blob: c238c217543e01aa1b3a33d11f250eac49e14f70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_SERVICES_NETWORK_UDP_SOCKET_IMPL_H_
#define MOJO_SERVICES_NETWORK_UDP_SOCKET_IMPL_H_

#include <stddef.h>
#include <stdint.h>

#include <deque>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "mojo/application/public/cpp/app_lifetime_helper.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/services/network/public/interfaces/udp_socket.mojom.h"
#include "net/base/ip_endpoint.h"
#include "net/udp/udp_socket.h"

namespace net {
class IOBuffer;
class IOBufferWithSize;
}

namespace mojo {

class UDPSocketImpl : public UDPSocket {
 public:
  // The lifetime of a new UDPSocketImpl is bound to the connection associated
  // with |request|.
  UDPSocketImpl(InterfaceRequest<UDPSocket> request,
                scoped_ptr<mojo::AppRefCount> app_refcount);
  ~UDPSocketImpl() override;

  // UDPSocket implementation.
  void AllowAddressReuse(
      const Callback<void(NetworkErrorPtr)>& callback) override;

  void Bind(NetAddressPtr addr,
            const Callback<void(NetworkErrorPtr,
                                NetAddressPtr,
                                InterfaceRequest<UDPSocketReceiver>)>& callback)
      override;

  void Connect(NetAddressPtr remote_addr,
               const Callback<void(NetworkErrorPtr,
                                   NetAddressPtr,
                                   InterfaceRequest<UDPSocketReceiver>)>&
                   callback) override;

  void SetSendBufferSize(
      uint32_t size,
      const Callback<void(NetworkErrorPtr)>& callback) override;

  void SetReceiveBufferSize(
      uint32_t size,
      const Callback<void(NetworkErrorPtr)>& callback) override;

  void NegotiateMaxPendingSendRequests(
      uint32_t requested_size,
      const Callback<void(uint32_t)>& callback) override;

  void ReceiveMore(uint32_t datagram_number) override;

  void SendTo(NetAddressPtr dest_addr,
              Array<uint8_t> data,
              const Callback<void(NetworkErrorPtr)>& callback) override;

 private:
  enum State {
    NOT_BOUND_OR_CONNECTED,
    BOUND,
    CONNECTED
  };

  struct PendingSendRequest {
    PendingSendRequest();
    ~PendingSendRequest();

    NetAddressPtr addr;
    Array<uint8_t> data;
    Callback<void(NetworkErrorPtr)> callback;
  };

  void DoRecvFrom();
  void DoSendTo(NetAddressPtr addr,
                Array<uint8_t> data,
                const Callback<void(NetworkErrorPtr)>& callback);

  void OnRecvFromCompleted(int net_result);
  void OnSendToCompleted(const Callback<void(NetworkErrorPtr)>& callback,
                         int net_result);

  bool IsBoundOrConnected() const {
    return state_ == BOUND || state_ == CONNECTED;
  }

  StrongBinding<UDPSocket> binding_;

  net::UDPSocket socket_;

  State state_;

  bool allow_address_reuse_;

  // Non-null when there is a pending RecvFrom operation on |socket_|.
  scoped_refptr<net::IOBuffer> recvfrom_buffer_;
  // Non-null when there is a pending SendTo operation on |socket_|.
  scoped_refptr<net::IOBufferWithSize> sendto_buffer_;

  // The address of the pending RecvFrom operation, if any.
  net::IPEndPoint recvfrom_address_;

  // The interface which gets data from fulfilled receive requests.
  UDPSocketReceiverPtr receiver_;

  // How many more packets the client side expects to receive.
  size_t remaining_recv_slots_;

  // The queue owns the PendingSendRequest instances.
  std::deque<PendingSendRequest*> pending_send_requests_;
  // The maximum size of the |pending_send_requests_| queue.
  size_t max_pending_send_requests_;

  scoped_ptr<mojo::AppRefCount> app_refcount_;

  DISALLOW_COPY_AND_ASSIGN(UDPSocketImpl);
};

}  // namespace mojo

#endif  // MOJO_SERVICES_NETWORK_UDP_SOCKET_IMPL_H_