1// Copyright 2014 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 NET_SOCKET_UNIX_DOMAIN_SERVER_SOCKET_POSIX_H_
6#define NET_SOCKET_UNIX_DOMAIN_SERVER_SOCKET_POSIX_H_
7
8#include <sys/types.h>
9
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/callback.h"
14#include "base/macros.h"
15#include "base/memory/scoped_ptr.h"
16#include "net/base/net_export.h"
17#include "net/socket/server_socket.h"
18#include "net/socket/socket_descriptor.h"
19
20namespace net {
21
22class SocketLibevent;
23
24// Unix Domain Server Socket Implementation. Supports abstract namespaces on
25// Linux and Android.
26class NET_EXPORT UnixDomainServerSocket : public ServerSocket {
27 public:
28  // Credentials of a peer process connected to the socket.
29  struct NET_EXPORT Credentials {
30#if defined(OS_LINUX) || defined(OS_ANDROID)
31    // Linux/Android API provides more information about the connected peer
32    // than Windows/OS X. It's useful for permission-based authorization on
33    // Android.
34    pid_t process_id;
35#endif
36    uid_t user_id;
37    gid_t group_id;
38  };
39
40  // Callback that returns whether the already connected client, identified by
41  // its credentials, is allowed to keep the connection open. Note that
42  // the socket is closed immediately in case the callback returns false.
43  typedef base::Callback<bool (const Credentials&)> AuthCallback;
44
45  UnixDomainServerSocket(const AuthCallback& auth_callack,
46                         bool use_abstract_namespace);
47  virtual ~UnixDomainServerSocket();
48
49  // Gets credentials of peer to check permissions.
50  static bool GetPeerCredentials(SocketDescriptor socket_fd,
51                                 Credentials* credentials);
52
53  // ServerSocket implementation.
54  virtual int Listen(const IPEndPoint& address, int backlog) OVERRIDE;
55  virtual int ListenWithAddressAndPort(const std::string& unix_domain_path,
56                                       int port_unused,
57                                       int backlog) OVERRIDE;
58  virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE;
59  virtual int Accept(scoped_ptr<StreamSocket>* socket,
60                     const CompletionCallback& callback) OVERRIDE;
61
62  // Accepts an incoming connection on |listen_socket_|, but passes back
63  // a raw SocketDescriptor instead of a StreamSocket.
64  int AcceptSocketDescriptor(SocketDescriptor* socket_descriptor,
65                             const CompletionCallback& callback);
66
67 private:
68  // A callback to wrap the setting of the out-parameter to Accept().
69  // This allows the internal machinery of that call to be implemented in
70  // a manner that's agnostic to the caller's desired output.
71  typedef base::Callback<void(scoped_ptr<SocketLibevent>)> SetterCallback;
72
73  int DoAccept(const SetterCallback& setter_callback,
74               const CompletionCallback& callback);
75  void AcceptCompleted(const SetterCallback& setter_callback,
76                       const CompletionCallback& callback,
77                       int rv);
78  bool AuthenticateAndGetStreamSocket(const SetterCallback& setter_callback);
79
80  scoped_ptr<SocketLibevent> listen_socket_;
81  const AuthCallback auth_callback_;
82  const bool use_abstract_namespace_;
83
84  scoped_ptr<SocketLibevent> accept_socket_;
85
86  DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocket);
87};
88
89}  // namespace net
90
91#endif  // NET_SOCKET_UNIX_DOMAIN_SOCKET_POSIX_H_
92