File: udp_socket_filter.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (140 lines) | stat: -rw-r--r-- 5,489 bytes parent folder | download | duplicates (11)
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
134
135
136
137
138
139
140
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_PROXY_UDP_SOCKET_FILTER_H_
#define PPAPI_PROXY_UDP_SOCKET_FILTER_H_

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

#include <memory>
#include <string>
#include <unordered_map>

#include "base/compiler_specific.h"
#include "base/containers/queue.h"
#include "base/memory/ref_counted.h"
#include "ppapi/c/ppb_udp_socket.h"
#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/proxy/plugin_resource.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/proxy/resource_message_filter.h"
#include "ppapi/shared_impl/tracked_callback.h"

namespace ppapi {
namespace proxy {

class ResourceMessageReplyParams;

// Handles receiving UDP packets on the IO thread so that when the recipient is
// not on the main thread, we can post directly to the appropriate thread.
class PPAPI_PROXY_EXPORT UDPSocketFilter : public ResourceMessageFilter {
 public:
  UDPSocketFilter();

  // All these are called on whatever thread the plugin wants, while already
  // holding the ppapi::ProxyLock. The "slot_available_callback" will be invoked
  // whenever we detect that a slot is now available, so that the client can
  // take appropriate action (like informing the host we can receive another
  // buffer). It will always be run with the ProxyLock.
  void AddUDPResource(PP_Instance instance,
                      PP_Resource resource,
                      bool private_api,
                      base::RepeatingClosure slot_available_callback);
  void RemoveUDPResource(PP_Resource resource);
  // Note, the slot_available_callback that was provided to AddUDPResource may
  // be invoked during the RequestData call; this gives the client the
  // opportunity to post a message to the host immediately.
  int32_t RequestData(PP_Resource resource,
                      int32_t num_bytes,
                      char* buffer,
                      PP_Resource* addr,
                      const scoped_refptr<TrackedCallback>& callback);

  // ResourceMessageFilter implementation.
  bool OnResourceReplyReceived(const ResourceMessageReplyParams& reply_params,
                               const IPC::Message& nested_msg) override;

  PP_NetAddress_Private GetLastAddrPrivate(PP_Resource resource) const;

  // The maximum number of bytes that each
  // PpapiPluginMsg_PPBUDPSocket_PushRecvResult message is allowed to carry.
  static const int32_t kMaxReadSize;
  // The maximum number that we allow for setting
  // PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE. This number is only for input
  // argument sanity check, it doesn't mean the browser guarantees to support
  // such a buffer size.
  static const int32_t kMaxReceiveBufferSize;
  // The maximum number of received packets that we allow instances of this
  // class to buffer.
  static const size_t kPluginReceiveBufferSlots;

 private:
  // The queue of received data intended for 1 UDPSocketResourceBase. All usage
  // must be protected by UDPSocketFilter::lock_.
  class RecvQueue {
   public:
    explicit RecvQueue(PP_Instance instance,
                       bool private_api,
                       base::RepeatingClosure slot_available_callback);
    ~RecvQueue();

    // Called on the IO thread when data is received. It will post |callback_|
    // if it's valid, otherwise push the data on buffers_.
    // The ppapi::ProxyLock should *not* be held, and won't be acquired.
    void DataReceivedOnIOThread(int32_t result,
                                const std::string& d,
                                const PP_NetAddress_Private& addr);
    // Called on whatever thread the plugin chooses. Must already hold the
    // PpapiProxyLock. Returns a code from pp_errors.h, or a positive number.
    //
    // Note, the out-params are owned by the plugin, and if the request can't be
    // handled immediately, they will be written later just before the callback
    // is invoked.
    int32_t RequestData(int32_t num_bytes,
                        char* buffer_out,
                        PP_Resource* addr_out,
                        const scoped_refptr<TrackedCallback>& callback);
    PP_NetAddress_Private GetLastAddrPrivate() const;

   private:
    struct RecvBuffer {
      int32_t result;
      std::string data;
      PP_NetAddress_Private addr;
    };
    base::queue<RecvBuffer> recv_buffers_;

    PP_Instance pp_instance_;
    scoped_refptr<ppapi::TrackedCallback> recvfrom_callback_;
    char* read_buffer_;
    int32_t bytes_to_read_;
    PP_Resource* recvfrom_addr_resource_;
    PP_NetAddress_Private last_recvfrom_addr_;
    bool private_api_;
    // Callback to invoke when a UDP receive slot is available.
    base::RepeatingClosure slot_available_callback_;
  };

 private:
  // This is deleted via RefCountedThreadSafe (see ResourceMessageFilter).
  ~UDPSocketFilter();
  void OnPluginMsgPushRecvResult(const ResourceMessageReplyParams& params,
                                 int32_t result,
                                 const std::string& data,
                                 const PP_NetAddress_Private& addr);

  // lock_ protects queues_.
  //
  // Lock order (if >1 acquired):
  // 1 ppapi::ProxyLock
  // \-->2 Filter lock_
  mutable base::Lock lock_;
  std::unordered_map<PP_Resource, std::unique_ptr<RecvQueue>> queues_;
};

}  // namespace proxy
}  // namespace ppapi

#endif  // PPAPI_PROXY_UDP_SOCKET_FILTER_H_