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