tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ipc_channel_win.h (5244B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 
      7 #ifndef CHROME_COMMON_IPC_CHANNEL_WIN_H_
      8 #define CHROME_COMMON_IPC_CHANNEL_WIN_H_
      9 
     10 #include "chrome/common/ipc_channel.h"
     11 #include "chrome/common/ipc_message.h"
     12 
     13 #include <atomic>
     14 
     15 #include "base/message_loop.h"
     16 #include "base/process.h"
     17 #include "base/task.h"
     18 #include "nsISupportsImpl.h"
     19 
     20 #include "mozilla/EventTargetCapability.h"
     21 #include "mozilla/Maybe.h"
     22 #include "mozilla/EventTargetAndLockCapability.h"
     23 #include "mozilla/Mutex.h"
     24 #include "mozilla/Queue.h"
     25 #include "mozilla/UniquePtr.h"
     26 
     27 namespace IPC {
     28 
     29 class ChannelWin : public Channel, public MessageLoopForIO::IOHandler {
     30 public:
     31  ChannelWin(mozilla::UniqueFileHandle pipe, Mode mode,
     32             base::ProcessId other_pid);
     33 
     34  bool Connect(Listener* listener) MOZ_EXCLUDES(SendMutex()) override;
     35  void Close() MOZ_EXCLUDES(SendMutex()) override;
     36  // NOTE: `Send` may be called on threads other than the I/O thread.
     37  bool Send(mozilla::UniquePtr<Message> message)
     38      MOZ_EXCLUDES(SendMutex()) override;
     39 
     40  void SetOtherPid(base::ProcessId other_pid) override;
     41 
     42  const ChannelKind* GetKind() const override { return &sKind; }
     43 
     44  static const ChannelKind sKind;
     45 
     46 private:
     47  ~ChannelWin() {
     48    IOThread().AssertOnCurrentThread();
     49    if (pipe_ != INVALID_HANDLE_VALUE ||
     50        other_process_ != INVALID_HANDLE_VALUE) {
     51      Close();
     52    }
     53  }
     54 
     55  static bool CreateRawPipe(ChannelHandle* server, ChannelHandle* client);
     56  static uint32_t NumRelayedAttachments(const IPC::Message& message);
     57  static bool IsValidHandle(const ChannelHandle& handle);
     58 
     59  void Init(Mode mode) MOZ_REQUIRES(SendMutex(), IOThread());
     60 
     61  void OutputQueuePush(mozilla::UniquePtr<Message> msg)
     62      MOZ_REQUIRES(SendMutex());
     63  void OutputQueuePop() MOZ_REQUIRES(SendMutex());
     64 
     65  bool EnqueueHelloMessage() MOZ_REQUIRES(SendMutex(), IOThread());
     66  void MaybeOpenProcessHandle() MOZ_REQUIRES(SendMutex(), IOThread());
     67  void CloseLocked() MOZ_REQUIRES(SendMutex(), IOThread());
     68 
     69  bool ProcessIncomingMessages(MessageLoopForIO::IOContext* context,
     70                               DWORD bytes_read, bool was_pending)
     71      MOZ_REQUIRES(IOThread());
     72  bool ProcessOutgoingMessages(MessageLoopForIO::IOContext* context,
     73                               DWORD bytes_written, bool was_pending)
     74      MOZ_REQUIRES(SendMutex());
     75 
     76  // Called on a Message immediately before it is sent/recieved to transfer
     77  // handles to the remote process, or accept handles from the remote process.
     78  bool AcceptHandles(Message& msg) MOZ_REQUIRES(IOThread());
     79  bool TransferHandles(Message& msg) MOZ_REQUIRES(SendMutex());
     80 
     81  // MessageLoop::IOHandler implementation.
     82  virtual void OnIOCompleted(MessageLoopForIO::IOContext* context,
     83                             DWORD bytes_transfered, DWORD error);
     84 
     85 private:
     86  Mode mode_ MOZ_GUARDED_BY(chan_cap_);
     87 
     88  struct State {
     89    explicit State(ChannelWin* channel);
     90    ~State();
     91    MessageLoopForIO::IOContext context;
     92    // When there is pending I/O, this holds a strong reference to the
     93    // ChannelWin to prevent it from going away.
     94    RefPtr<ChannelWin> is_pending;
     95  };
     96 
     97  State input_state_ MOZ_GUARDED_BY(IOThread());
     98  State output_state_ MOZ_GUARDED_BY(SendMutex());
     99 
    100  HANDLE pipe_ MOZ_GUARDED_BY(chan_cap_) = INVALID_HANDLE_VALUE;
    101 
    102  Listener* listener_ MOZ_GUARDED_BY(IOThread()) = nullptr;
    103 
    104  // Messages to be sent are queued here.
    105  mozilla::Queue<mozilla::UniquePtr<Message>, 64> output_queue_
    106      MOZ_GUARDED_BY(SendMutex());
    107 
    108  // If sending a message blocks then we use this iterator to keep track of
    109  // where in the message we are. It gets reset when the message is finished
    110  // sending.
    111  mozilla::Maybe<Pickle::BufferList::IterImpl> partial_write_iter_
    112      MOZ_GUARDED_BY(SendMutex());
    113 
    114  // We read from the pipe into this buffer
    115  mozilla::UniquePtr<char[]> input_buf_ MOZ_GUARDED_BY(IOThread());
    116  size_t input_buf_offset_ MOZ_GUARDED_BY(IOThread()) = 0;
    117 
    118  // Large incoming messages that span multiple pipe buffers get built-up in the
    119  // buffers of this message.
    120  mozilla::UniquePtr<Message> incoming_message_ MOZ_GUARDED_BY(IOThread());
    121 
    122  // Will be set to `true` until `Connect()` has been called.
    123  bool waiting_connect_ MOZ_GUARDED_BY(chan_cap_) = true;
    124 
    125  // This flag is set when processing incoming messages.  It is used to
    126  // avoid recursing through ProcessIncomingMessages, which could cause
    127  // problems.  TODO(darin): make this unnecessary
    128  bool processing_incoming_ MOZ_GUARDED_BY(IOThread()) = false;
    129 
    130  // We keep track of the PID of the other side of this channel so that we can
    131  // record this when generating logs of IPC messages.
    132  base::ProcessId other_pid_ MOZ_GUARDED_BY(chan_cap_) =
    133      base::kInvalidProcessId;
    134 
    135  // A privileged process handle used to transfer HANDLEs to and from the remote
    136  // process. This will only be used if `mode_ == MODE_BROKER_SERVER`.
    137  HANDLE other_process_ MOZ_GUARDED_BY(chan_cap_) = INVALID_HANDLE_VALUE;
    138 };
    139 
    140 }  // namespace IPC
    141 
    142 #endif  // CHROME_COMMON_IPC_CHANNEL_WIN_H_