OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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 #include "net/socket/unix_domain_listen_socket_posix.h" | |
6 | |
7 #include <cstring> | |
8 #include <string> | |
9 | |
10 #include <errno.h> | |
11 #include <sys/socket.h> | |
12 #include <sys/stat.h> | |
13 #include <sys/types.h> | |
14 #include <sys/un.h> | |
15 #include <unistd.h> | |
mmenke
2014/06/30 18:26:51
nit: C++ headers should got before C ones.
byungchul
2014/07/09 22:42:19
Done in https://codereview.chromium.org/376323002/
| |
16 | |
17 #include "base/bind.h" | |
18 #include "base/callback.h" | |
19 #include "base/posix/eintr_wrapper.h" | |
20 #include "base/threading/platform_thread.h" | |
21 #include "build/build_config.h" | |
22 #include "net/base/net_errors.h" | |
23 #include "net/base/net_util.h" | |
24 #include "net/socket/socket_descriptor.h" | |
25 #include "net/socket/unix_domain_client_socket_posix.h" | |
26 | |
27 namespace net { | |
28 | |
29 namespace { | |
30 | |
31 int CreateAndBind(const std::string& socket_path, | |
32 bool use_abstract_namespace, | |
33 SocketDescriptor* socket_fd) { | |
34 SockaddrStorage address; | |
35 if (!UnixDomainClientSocket::FillAddress(socket_path, | |
36 use_abstract_namespace, | |
37 &address)) | |
38 return ERR_ADDRESS_INVALID; | |
39 | |
40 SocketDescriptor s = CreatePlatformSocket(PF_UNIX, SOCK_STREAM, 0); | |
41 if (s == kInvalidSocket) | |
42 return errno ? MapSystemError(errno) : ERR_UNEXPECTED; | |
43 | |
44 if (bind(s, address.addr, address.addr_len) < 0) { | |
45 int rv = MapSystemError(errno); | |
46 close(s); | |
47 PLOG(ERROR) << "Could not bind unix domain socket to " << socket_path | |
48 << (use_abstract_namespace ? " (with abstract namespace)" : ""); | |
49 return rv; | |
50 } | |
51 | |
52 DCHECK(socket_fd); | |
53 *socket_fd = s; | |
54 return OK; | |
55 } | |
56 | |
57 } // namespace | |
58 | |
59 // static | |
60 scoped_ptr<UnixDomainListenSocket> | |
61 UnixDomainListenSocket::CreateAndListenInternal( | |
62 const std::string& path, | |
63 const std::string& fallback_path, | |
64 StreamListenSocket::Delegate* del, | |
65 const AuthCallback& auth_callback, | |
66 bool use_abstract_namespace) { | |
67 SocketDescriptor socket_fd = kInvalidSocket; | |
68 int rv = CreateAndBind(path, use_abstract_namespace, &socket_fd); | |
69 if (rv != OK && !fallback_path.empty()) | |
70 rv = CreateAndBind(fallback_path, use_abstract_namespace, &socket_fd); | |
71 if (rv != OK) | |
72 return scoped_ptr<UnixDomainListenSocket>(); | |
73 scoped_ptr<UnixDomainListenSocket> sock( | |
74 new UnixDomainListenSocket(socket_fd, del, auth_callback)); | |
75 sock->Listen(); | |
76 return sock.Pass(); | |
77 } | |
78 | |
79 // static | |
80 scoped_ptr<UnixDomainListenSocket> UnixDomainListenSocket::CreateAndListen( | |
81 const std::string& path, | |
82 StreamListenSocket::Delegate* del, | |
83 const AuthCallback& auth_callback) { | |
84 return CreateAndListenInternal(path, "", del, auth_callback, false); | |
85 } | |
86 | |
87 #if defined(SOCKET_ABSTRACT_NAMESPACE_SUPPORTED) | |
88 // static | |
89 scoped_ptr<UnixDomainListenSocket> | |
90 UnixDomainListenSocket::CreateAndListenWithAbstractNamespace( | |
91 const std::string& path, | |
92 const std::string& fallback_path, | |
93 StreamListenSocket::Delegate* del, | |
94 const AuthCallback& auth_callback) { | |
95 return | |
96 CreateAndListenInternal(path, fallback_path, del, auth_callback, true); | |
97 } | |
98 #endif | |
99 | |
100 UnixDomainListenSocket::UnixDomainListenSocket( | |
101 SocketDescriptor s, | |
102 StreamListenSocket::Delegate* del, | |
103 const AuthCallback& auth_callback) | |
104 : StreamListenSocket(s, del), | |
105 auth_callback_(auth_callback) {} | |
106 | |
107 UnixDomainListenSocket::~UnixDomainListenSocket() {} | |
108 | |
109 void UnixDomainListenSocket::Accept() { | |
110 SocketDescriptor conn = StreamListenSocket::AcceptSocket(); | |
111 if (conn == kInvalidSocket) | |
112 return; | |
113 uid_t user_id; | |
114 gid_t group_id; | |
115 if (!UnixDomainServerSocket::GetPeerIds(conn, &user_id, &group_id) || | |
116 !auth_callback_.Run(user_id, group_id)) { | |
117 if (IGNORE_EINTR(close(conn)) < 0) | |
118 LOG(ERROR) << "close() error"; | |
119 return; | |
120 } | |
121 scoped_ptr<UnixDomainListenSocket> sock( | |
122 new UnixDomainListenSocket(conn, socket_delegate_, auth_callback_)); | |
123 // It's up to the delegate to AddRef if it wants to keep it around. | |
124 sock->WatchSocket(WAITING_READ); | |
125 socket_delegate_->DidAccept(this, sock.PassAs<StreamListenSocket>()); | |
126 } | |
127 | |
128 UnixDomainListenSocketFactory::UnixDomainListenSocketFactory( | |
129 const std::string& path, | |
130 const UnixDomainListenSocket::AuthCallback& auth_callback) | |
131 : path_(path), | |
132 auth_callback_(auth_callback) {} | |
133 | |
134 UnixDomainListenSocketFactory::~UnixDomainListenSocketFactory() {} | |
135 | |
136 scoped_ptr<StreamListenSocket> UnixDomainListenSocketFactory::CreateAndListen( | |
137 StreamListenSocket::Delegate* delegate) const { | |
138 return UnixDomainListenSocket::CreateAndListen( | |
139 path_, delegate, auth_callback_).PassAs<StreamListenSocket>(); | |
140 } | |
141 | |
142 #if defined(SOCKET_ABSTRACT_NAMESPACE_SUPPORTED) | |
143 | |
144 UnixDomainListenSocketWithAbstractNamespaceFactory:: | |
145 UnixDomainListenSocketWithAbstractNamespaceFactory( | |
146 const std::string& path, | |
147 const std::string& fallback_path, | |
148 const UnixDomainListenSocket::AuthCallback& auth_callback) | |
149 : UnixDomainListenSocketFactory(path, auth_callback), | |
150 fallback_path_(fallback_path) {} | |
151 | |
152 UnixDomainListenSocketWithAbstractNamespaceFactory:: | |
153 ~UnixDomainListenSocketWithAbstractNamespaceFactory() {} | |
154 | |
155 scoped_ptr<StreamListenSocket> | |
156 UnixDomainListenSocketWithAbstractNamespaceFactory::CreateAndListen( | |
157 StreamListenSocket::Delegate* delegate) const { | |
158 return UnixDomainListenSocket::CreateAndListenWithAbstractNamespace( | |
159 path_, fallback_path_, delegate, auth_callback_) | |
160 .PassAs<StreamListenSocket>(); | |
161 } | |
162 | |
163 #endif | |
164 | |
165 } // namespace net | |
OLD | NEW |