Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2013 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 PPAPI_PROXY_SERIALIZED_HANDLES_H_
      6 #define PPAPI_PROXY_SERIALIZED_HANDLES_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/logging.h"
     13 #include "base/memory/shared_memory.h"
     14 #include "build/build_config.h"
     15 #include "ipc/ipc_platform_file.h"
     16 #include "ppapi/proxy/ppapi_proxy_export.h"
     17 
     18 class Pickle;
     19 
     20 namespace ppapi {
     21 namespace proxy {
     22 
     23 // SerializedHandle is a unified structure for holding a handle (e.g., a shared
     24 // memory handle, socket descriptor, etc). This is useful for passing handles in
     25 // resource messages and also makes it easier to translate handles in
     26 // NaClIPCAdapter for use in NaCl.
     27 class PPAPI_PROXY_EXPORT SerializedHandle {
     28  public:
     29   enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE, FILE };
     30   struct Header {
     31     Header() : type(INVALID), size(0), open_flag(0) {}
     32     Header(Type type_arg, uint32 size_arg, int32 open_flag_arg)
     33         : type(type_arg), size(size_arg), open_flag(open_flag_arg) {
     34     }
     35     Type type;
     36     uint32 size;
     37     int32 open_flag;
     38   };
     39 
     40   SerializedHandle();
     41   // Create an invalid handle of the given type.
     42   explicit SerializedHandle(Type type);
     43 
     44   // Create a shared memory handle.
     45   SerializedHandle(const base::SharedMemoryHandle& handle, uint32 size);
     46 
     47   // Create a socket, channel or file handle.
     48   SerializedHandle(const Type type,
     49                    const IPC::PlatformFileForTransit& descriptor);
     50 
     51   Type type() const { return type_; }
     52   bool is_shmem() const { return type_ == SHARED_MEMORY; }
     53   bool is_socket() const { return type_ == SOCKET; }
     54   bool is_channel_handle() const { return type_ == CHANNEL_HANDLE; }
     55   bool is_file() const { return type_ == FILE; }
     56   const base::SharedMemoryHandle& shmem() const {
     57     DCHECK(is_shmem());
     58     return shm_handle_;
     59   }
     60   uint32 size() const {
     61     DCHECK(is_shmem());
     62     return size_;
     63   }
     64   const IPC::PlatformFileForTransit& descriptor() const {
     65     DCHECK(is_socket() || is_channel_handle() || is_file());
     66     return descriptor_;
     67   }
     68   int32 open_flag() const {
     69     return open_flag_;
     70   }
     71   void set_shmem(const base::SharedMemoryHandle& handle, uint32 size) {
     72     type_ = SHARED_MEMORY;
     73     shm_handle_ = handle;
     74     size_ = size;
     75 
     76     descriptor_ = IPC::InvalidPlatformFileForTransit();
     77   }
     78   void set_socket(const IPC::PlatformFileForTransit& socket) {
     79     type_ = SOCKET;
     80     descriptor_ = socket;
     81 
     82     shm_handle_ = base::SharedMemory::NULLHandle();
     83     size_ = 0;
     84   }
     85   void set_channel_handle(const IPC::PlatformFileForTransit& descriptor) {
     86     type_ = CHANNEL_HANDLE;
     87 
     88     descriptor_ = descriptor;
     89     shm_handle_ = base::SharedMemory::NULLHandle();
     90     size_ = 0;
     91   }
     92   void set_file_handle(const IPC::PlatformFileForTransit& descriptor,
     93                        int32 open_flag) {
     94     type_ = FILE;
     95 
     96     descriptor_ = descriptor;
     97     shm_handle_ = base::SharedMemory::NULLHandle();
     98     size_ = 0;
     99     open_flag_ = open_flag;
    100   }
    101   void set_null_shmem() {
    102     set_shmem(base::SharedMemory::NULLHandle(), 0);
    103   }
    104   void set_null_socket() {
    105     set_socket(IPC::InvalidPlatformFileForTransit());
    106   }
    107   void set_null_channel_handle() {
    108     set_channel_handle(IPC::InvalidPlatformFileForTransit());
    109   }
    110   void set_null_file_handle() {
    111     set_file_handle(IPC::InvalidPlatformFileForTransit(), 0);
    112   }
    113   bool IsHandleValid() const;
    114 
    115   Header header() const {
    116     return Header(type_, size_, open_flag_);
    117   }
    118 
    119   // Closes the handle and sets it to invalid.
    120   void Close();
    121 
    122   // Write/Read a Header, which contains all the data except the handle. This
    123   // allows us to write the handle in a platform-specific way, as is necessary
    124   // in NaClIPCAdapter to share handles with NaCl from Windows.
    125   static bool WriteHeader(const Header& hdr, Pickle* pickle);
    126   static bool ReadHeader(PickleIterator* iter, Header* hdr);
    127 
    128  private:
    129   // The kind of handle we're holding.
    130   Type type_;
    131 
    132   // We hold more members than we really need; we can't easily use a union,
    133   // because we hold non-POD types. But these types are pretty light-weight. If
    134   // we add more complex things later, we should come up with a more memory-
    135   // efficient strategy.
    136   // These are valid if type == SHARED_MEMORY.
    137   base::SharedMemoryHandle shm_handle_;
    138   uint32 size_;
    139 
    140   // This is valid if type == SOCKET || type == CHANNEL_HANDLE || type == FILE.
    141   IPC::PlatformFileForTransit descriptor_;
    142 
    143   // This is valid if type == FILE.
    144   int32 open_flag_;
    145 };
    146 
    147 }  // namespace proxy
    148 }  // namespace ppapi
    149 
    150 #endif  // PPAPI_PROXY_SERIALIZED_HANDLES_H_
    151