LCOV - code coverage report
Current view: top level - media/mtransport - nr_socket_prsock.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 35 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 25 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : // Original author: ekr@rtfm.com
       8             : 
       9             : /* Some source code here from nICEr. Copyright is:
      10             : 
      11             : Copyright (c) 2007, Adobe Systems, Incorporated
      12             : All rights reserved.
      13             : 
      14             : Redistribution and use in source and binary forms, with or without
      15             : modification, are permitted provided that the following conditions are
      16             : met:
      17             : 
      18             : * Redistributions of source code must retain the above copyright
      19             :   notice, this list of conditions and the following disclaimer.
      20             : 
      21             : * Redistributions in binary form must reproduce the above copyright
      22             :   notice, this list of conditions and the following disclaimer in the
      23             :   documentation and/or other materials provided with the distribution.
      24             : 
      25             : * Neither the name of Adobe Systems, Network Resonance nor the names of its
      26             :   contributors may be used to endorse or promote products derived from
      27             :   this software without specific prior written permission.
      28             : 
      29             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      30             : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      31             : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      32             : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      33             : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      34             : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      35             : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      36             : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      37             : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      38             : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      39             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      40             : */
      41             : 
      42             : 
      43             : // Implementation of nICEr/nr_socket that is tied to the Gecko
      44             : // SocketTransportService.
      45             : 
      46             : #ifndef nr_socket_prsock__
      47             : #define nr_socket_prsock__
      48             : 
      49             : #include <queue>
      50             : 
      51             : #include "nspr.h"
      52             : #include "prio.h"
      53             : 
      54             : #include "nsAutoPtr.h"
      55             : #include "nsCOMPtr.h"
      56             : #include "nsASocketHandler.h"
      57             : #include "nsISocketTransportService.h"
      58             : #include "nsXPCOM.h"
      59             : #include "nsIEventTarget.h"
      60             : #include "nsIUDPSocketChild.h"
      61             : #include "nsProxyRelease.h"
      62             : #include "nsThreadUtils.h"
      63             : 
      64             : #include "nsITCPSocketCallback.h"
      65             : #include "databuffer.h"
      66             : #include "m_cpp_utils.h"
      67             : #include "mozilla/ReentrantMonitor.h"
      68             : #include "mozilla/RefPtr.h"
      69             : #include "mozilla/TimeStamp.h"
      70             : #include "mozilla/ClearOnShutdown.h"
      71             : 
      72             : // Stub declaration for nICEr type
      73             : typedef struct nr_socket_vtbl_ nr_socket_vtbl;
      74             : typedef struct nr_socket_ nr_socket;
      75             : 
      76             : #if defined(MOZILLA_INTERNAL_API)
      77             : namespace mozilla {
      78             : namespace dom {
      79             : class TCPSocketChild;
      80             : }
      81             : }
      82             : #endif
      83             : 
      84             : namespace mozilla {
      85             : 
      86             : namespace net {
      87             :   union NetAddr;
      88             : }
      89             : 
      90             : class NrSocketBase {
      91             : public:
      92           0 :   NrSocketBase() : connect_invoked_(false), poll_flags_(0) {
      93           0 :     memset(cbs_, 0, sizeof(cbs_));
      94           0 :     memset(cb_args_, 0, sizeof(cb_args_));
      95           0 :     memset(&my_addr_, 0, sizeof(my_addr_));
      96           0 :   }
      97           0 :   virtual ~NrSocketBase() {}
      98             : 
      99             :   // Factory method; will create either an NrSocket, NrUdpSocketIpc, or
     100             :   // NrTcpSocketIpc as appropriate.
     101             :   static int CreateSocket(nr_transport_addr *addr, RefPtr<NrSocketBase> *sock);
     102             : 
     103             :   // the nr_socket APIs
     104             :   virtual int create(nr_transport_addr *addr) = 0;
     105             :   virtual int sendto(const void *msg, size_t len,
     106             :                      int flags, nr_transport_addr *to) = 0;
     107             :   virtual int recvfrom(void * buf, size_t maxlen,
     108             :                        size_t *len, int flags,
     109             :                        nr_transport_addr *from) = 0;
     110             :   virtual int getaddr(nr_transport_addr *addrp) = 0;
     111             :   virtual void close() = 0;
     112             :   virtual int connect(nr_transport_addr *addr) = 0;
     113             :   virtual int write(const void *msg, size_t len, size_t *written) = 0;
     114             :   virtual int read(void* buf, size_t maxlen, size_t *len) = 0;
     115             :   virtual int listen(int backlog) = 0;
     116             :   virtual int accept(nr_transport_addr *addrp, nr_socket **sockp) = 0;
     117             : 
     118             :    // Implementations of the async_event APIs
     119             :   virtual int async_wait(int how, NR_async_cb cb, void *cb_arg,
     120             :                          char *function, int line);
     121             :   virtual int cancel(int how);
     122             : 
     123             :   // nsISupport reference counted interface
     124             :   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
     125             : 
     126           0 :   uint32_t poll_flags() {
     127           0 :     return poll_flags_;
     128             :   }
     129             : 
     130             :   virtual nr_socket_vtbl *vtbl();  // To access in test classes.
     131             : 
     132             :   static TimeStamp short_term_violation_time();
     133             :   static TimeStamp long_term_violation_time();
     134           0 :   const nr_transport_addr& my_addr() const {
     135           0 :     return my_addr_;
     136             :   }
     137             : 
     138             :   void fire_callback(int how);
     139             : 
     140             : protected:
     141             : 
     142             :   bool connect_invoked_;
     143             :   nr_transport_addr my_addr_;
     144             : 
     145             : private:
     146             :   NR_async_cb cbs_[NR_ASYNC_WAIT_WRITE + 1];
     147             :   void *cb_args_[NR_ASYNC_WAIT_WRITE + 1];
     148             :   uint32_t poll_flags_;
     149             : };
     150             : 
     151             : class NrSocket : public NrSocketBase,
     152             :                  public nsASocketHandler {
     153             : public:
     154           0 :   NrSocket() : fd_(nullptr) {}
     155             : 
     156             :   // Implement nsASocket
     157             :   virtual void OnSocketReady(PRFileDesc *fd, int16_t outflags) override;
     158             :   virtual void OnSocketDetached(PRFileDesc *fd) override;
     159             :   virtual void IsLocal(bool *aIsLocal) override;
     160           0 :   virtual uint64_t ByteCountSent() override { return 0; }
     161           0 :   virtual uint64_t ByteCountReceived() override { return 0; }
     162             : 
     163             :   // nsISupports methods
     164             :   NS_DECL_THREADSAFE_ISUPPORTS
     165             : 
     166             :   // Implementations of the async_event APIs
     167             :   virtual int async_wait(int how, NR_async_cb cb, void *cb_arg,
     168             :                          char *function, int line) override;
     169             :   virtual int cancel(int how) override;
     170             : 
     171             : 
     172             :   // Implementations of the nr_socket APIs
     173             :   virtual int create(nr_transport_addr *addr) override; // (really init, but it's called create)
     174             :   virtual int sendto(const void *msg, size_t len,
     175             :                      int flags, nr_transport_addr *to) override;
     176             :   virtual int recvfrom(void * buf, size_t maxlen,
     177             :                        size_t *len, int flags,
     178             :                        nr_transport_addr *from) override;
     179             :   virtual int getaddr(nr_transport_addr *addrp) override;
     180             :   virtual void close() override;
     181             :   virtual int connect(nr_transport_addr *addr) override;
     182             :   virtual int write(const void *msg, size_t len, size_t *written) override;
     183             :   virtual int read(void* buf, size_t maxlen, size_t *len) override;
     184             :   virtual int listen(int backlog) override;
     185             :   virtual int accept(nr_transport_addr *addrp, nr_socket **sockp) override;
     186             : 
     187             : protected:
     188           0 :   virtual ~NrSocket() {
     189           0 :     if (fd_)
     190           0 :       PR_Close(fd_);
     191           0 :   }
     192             : 
     193             :   DISALLOW_COPY_ASSIGN(NrSocket);
     194             : 
     195             :   PRFileDesc *fd_;
     196             :   nsCOMPtr<nsIEventTarget> ststhread_;
     197             : };
     198             : 
     199             : struct nr_udp_message {
     200           0 :   nr_udp_message(const PRNetAddr &from, nsAutoPtr<DataBuffer> &data)
     201           0 :       : from(from), data(data) {
     202           0 :   }
     203             : 
     204           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nr_udp_message);
     205             : 
     206             :   PRNetAddr from;
     207             :   nsAutoPtr<DataBuffer> data;
     208             : 
     209             : private:
     210           0 :   ~nr_udp_message() {}
     211             :   DISALLOW_COPY_ASSIGN(nr_udp_message);
     212             : };
     213             : 
     214             : class NrSocketIpc : public NrSocketBase {
     215             : public:
     216             : 
     217             :   enum NrSocketIpcState {
     218             :     NR_INIT,
     219             :     NR_CONNECTING,
     220             :     NR_CONNECTED,
     221             :     NR_CLOSING,
     222             :     NR_CLOSED,
     223             :   };
     224             : 
     225             :   NrSocketIpc(nsIEventTarget* aThread);
     226             : 
     227             : protected:
     228             :   nsCOMPtr<nsIEventTarget> sts_thread_;
     229             :   // Note: for UDP PBackground, this is a thread held by SingletonThreadHolder.
     230             :   // For TCP PNecko, this is MainThread (and TCPSocket requires MainThread currently)
     231             :   const nsCOMPtr<nsIEventTarget> io_thread_;
     232           0 :   virtual ~NrSocketIpc() {};
     233             : 
     234             : private:
     235             :   DISALLOW_COPY_ASSIGN(NrSocketIpc);
     236             : };
     237             : 
     238             : class NrUdpSocketIpc : public NrSocketIpc {
     239             : public:
     240           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrUdpSocketIpc, override)
     241             : 
     242             :   NS_IMETHODIMP CallListenerError(const nsACString &message,
     243             :                                   const nsACString &filename,
     244             :                                   uint32_t line_number);
     245             :   NS_IMETHODIMP CallListenerReceivedData(const nsACString &host,
     246             :                                          uint16_t port,
     247             :                                          const uint8_t *data,
     248             :                                          uint32_t data_length);
     249             :   NS_IMETHODIMP CallListenerOpened();
     250             :   NS_IMETHODIMP CallListenerConnected();
     251             :   NS_IMETHODIMP CallListenerClosed();
     252             : 
     253             :   NrUdpSocketIpc();
     254             : 
     255             :   // Implementations of the NrSocketBase APIs
     256             :   virtual int create(nr_transport_addr *addr) override;
     257             :   virtual int sendto(const void *msg, size_t len,
     258             :                      int flags, nr_transport_addr *to) override;
     259             :   virtual int recvfrom(void * buf, size_t maxlen,
     260             :                        size_t *len, int flags,
     261             :                        nr_transport_addr *from) override;
     262             :   virtual int getaddr(nr_transport_addr *addrp) override;
     263             :   virtual void close() override;
     264             :   virtual int connect(nr_transport_addr *addr) override;
     265             :   virtual int write(const void *msg, size_t len, size_t *written) override;
     266             :   virtual int read(void* buf, size_t maxlen, size_t *len) override;
     267             :   virtual int listen(int backlog) override;
     268             :   virtual int accept(nr_transport_addr *addrp, nr_socket **sockp) override;
     269             : 
     270             : private:
     271             :   virtual ~NrUdpSocketIpc();
     272             : 
     273             :   DISALLOW_COPY_ASSIGN(NrUdpSocketIpc);
     274             : 
     275             :   nsresult SetAddress();  // Set the local address from parent info.
     276             : 
     277             :   // Main or private thread executors of the NrSocketBase APIs
     278             :   void create_i(const nsACString &host, const uint16_t port);
     279             :   void connect_i(const nsACString &host, const uint16_t port);
     280             :   void sendto_i(const net::NetAddr &addr, nsAutoPtr<DataBuffer> buf);
     281             :   void close_i();
     282             : #if defined(MOZILLA_INTERNAL_API) && !defined(MOZILLA_XPCOMRT_API)
     283             :   static void release_child_i(nsIUDPSocketChild* aChild);
     284             : #endif
     285             :   // STS thread executor
     286             :   void recv_callback_s(RefPtr<nr_udp_message> msg);
     287             : 
     288             :   ReentrantMonitor monitor_; // protects err_and state_
     289             :   bool err_;
     290             :   NrSocketIpcState state_;
     291             : 
     292             :   std::queue<RefPtr<nr_udp_message>> received_msgs_;
     293             : 
     294             :   RefPtr<nsIUDPSocketChild> socket_child_; // only accessed from the io_thread
     295             : };
     296             : 
     297             : // The socket child holds onto one of these, which just passes callbacks
     298             : // through and makes sure the ref to the NrSocketIpc is released on STS.
     299           0 : class NrUdpSocketIpcProxy : public nsIUDPSocketInternal {
     300             : public:
     301             :   NS_DECL_THREADSAFE_ISUPPORTS
     302             :   NS_DECL_NSIUDPSOCKETINTERNAL
     303             : 
     304             :   nsresult Init(const RefPtr<NrUdpSocketIpc>& socket);
     305             : 
     306             : private:
     307             :   virtual ~NrUdpSocketIpcProxy();
     308             : 
     309             :   RefPtr<NrUdpSocketIpc> socket_;
     310             :   nsCOMPtr<nsIEventTarget> sts_thread_;
     311             : };
     312             : 
     313             : struct nr_tcp_message {
     314           0 :   explicit nr_tcp_message(nsAutoPtr<DataBuffer> &data)
     315           0 :     : read_bytes(0)
     316           0 :     , data(data) {
     317           0 :   }
     318             : 
     319           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nr_tcp_message);
     320             : 
     321           0 :   const uint8_t *reading_pointer() const {
     322           0 :     return data->data() + read_bytes;
     323             :   }
     324             : 
     325           0 :   size_t unread_bytes() const {
     326           0 :     return data->len() - read_bytes;
     327             :   }
     328             : 
     329             :   size_t read_bytes;
     330             : 
     331             : private:
     332           0 :   ~nr_tcp_message() {}
     333             :   DISALLOW_COPY_ASSIGN(nr_tcp_message);
     334             : 
     335             :   nsAutoPtr<DataBuffer> data;
     336             : };
     337             : 
     338             : #if defined(MOZILLA_INTERNAL_API) && !defined(MOZILLA_XPCOMRT_API)
     339             : class NrTcpSocketIpc : public NrSocketIpc,
     340             :                        public nsITCPSocketCallback {
     341             : public:
     342             :   NS_DECL_THREADSAFE_ISUPPORTS
     343             :   NS_DECL_NSITCPSOCKETCALLBACK
     344             : 
     345             :   explicit NrTcpSocketIpc(nsIThread* aThread);
     346             : 
     347             :   // Implementations of the NrSocketBase APIs
     348             :   virtual int create(nr_transport_addr *addr) override;
     349             :   virtual int sendto(const void *msg, size_t len,
     350             :                      int flags, nr_transport_addr *to) override;
     351             :   virtual int recvfrom(void * buf, size_t maxlen,
     352             :                        size_t *len, int flags,
     353             :                        nr_transport_addr *from) override;
     354             :   virtual int getaddr(nr_transport_addr *addrp) override;
     355             :   virtual void close() override;
     356             :   virtual int connect(nr_transport_addr *addr) override;
     357             :   virtual int write(const void *msg, size_t len, size_t *written) override;
     358             :   virtual int read(void* buf, size_t maxlen, size_t *len) override;
     359             :   virtual int listen(int backlog) override;
     360             :   virtual int accept(nr_transport_addr *addrp, nr_socket **sockp) override;
     361             : 
     362             : private:
     363             :   class TcpSocketReadyRunner;
     364             :   DISALLOW_COPY_ASSIGN(NrTcpSocketIpc);
     365             :   virtual ~NrTcpSocketIpc();
     366             : 
     367             :   // Main thread executors of the NrSocketBase APIs
     368             :   void connect_i(const nsACString &remote_addr,
     369             :                  uint16_t remote_port,
     370             :                  const nsACString &local_addr,
     371             :                  uint16_t local_port,
     372             :                  const nsACString &tls_host);
     373             :   void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf,
     374             :                uint32_t tracking_number);
     375             :   void close_i();
     376             : 
     377             :   static void release_child_i(dom::TCPSocketChild* aChild);
     378             : 
     379             :   // STS thread executor
     380             :   void message_sent_s(uint32_t bufferedAmount, uint32_t tracking_number);
     381             :   void recv_message_s(nr_tcp_message *msg);
     382             :   void update_state_s(NrSocketIpcState next_state);
     383             :   void maybe_post_socket_ready();
     384             : 
     385             :   // Accessed from UpdateReadyState (not sts_thread) to avoid sending
     386             :   // runnables when not needed
     387             :   NrSocketIpcState mirror_state_;
     388             : 
     389             :   // variables that can only be accessed on STS.
     390             :   NrSocketIpcState state_;
     391             :   std::queue<RefPtr<nr_tcp_message>> msg_queue_;
     392             :   uint32_t buffered_bytes_;
     393             :   uint32_t tracking_number_;
     394             :   std::deque<size_t> writes_in_flight_;
     395             : 
     396             :   // main thread.
     397             :   RefPtr<dom::TCPSocketChild> socket_child_;
     398             : };
     399             : #endif
     400             : 
     401             : int nr_netaddr_to_transport_addr(const net::NetAddr *netaddr,
     402             :                                  nr_transport_addr *addr,
     403             :                                  int protocol);
     404             : int nr_praddr_to_transport_addr(const PRNetAddr *praddr,
     405             :                                 nr_transport_addr *addr,
     406             :                                 int protocol, int keep);
     407             : int nr_transport_addr_get_addrstring_and_port(nr_transport_addr *addr,
     408             :                                               nsACString *host, int32_t *port);
     409             : }  // close namespace
     410             : #endif

Generated by: LCOV version 1.13