Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: net/socket/unix_domain_server_socket_posix.cc

Issue 376323002: Refactor unix domain socket. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix unittests because of incomplete reversion Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "net/socket/unix_domain_server_socket_posix.h"
6
7 #include <errno.h>
8 #include <sys/socket.h>
9 #include <sys/un.h>
10 #include <unistd.h>
11
12 #include "base/logging.h"
13 #include "net/base/net_errors.h"
14 #include "net/socket/socket_libevent.h"
15 #include "net/socket/unix_domain_client_socket_posix.h"
16
17 namespace net {
18
19 UnixDomainServerSocket::UnixDomainServerSocket(
20 const AuthCallback& auth_callback,
21 bool use_abstract_namespace)
22 : auth_callback_(auth_callback),
23 use_abstract_namespace_(use_abstract_namespace) {
24 DCHECK(!auth_callback_.is_null());
25 }
26
27 UnixDomainServerSocket::~UnixDomainServerSocket() {
28 }
29
30 // static
31 bool UnixDomainServerSocket::GetPeerIds(SocketDescriptor socket,
32 uid_t* user_id,
33 gid_t* group_id) {
34 #if defined(OS_LINUX) || defined(OS_ANDROID)
35 struct ucred user_cred;
36 socklen_t len = sizeof(user_cred);
37 if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &user_cred, &len) < 0)
38 return false;
39 *user_id = user_cred.uid;
40 *group_id = user_cred.gid;
41 return true;
42 #else
43 return getpeereid(socket, user_id, group_id) == 0;
44 #endif
45 }
46
47 int UnixDomainServerSocket::Listen(const IPEndPoint& address, int backlog) {
48 NOTIMPLEMENTED();
49 return ERR_NOT_IMPLEMENTED;
50 }
51
52 int UnixDomainServerSocket::ListenWithAddressAndPort(
53 const std::string& unix_domain_path,
54 int port_unused,
55 int backlog) {
56 DCHECK(!listen_socket_);
57
58 SockaddrStorage address;
59 if (!UnixDomainClientSocket::FillAddress(unix_domain_path,
60 use_abstract_namespace_,
61 &address)) {
62 return ERR_ADDRESS_INVALID;
63 }
64
65 listen_socket_.reset(new SocketLibevent);
66 int rv = listen_socket_->Open(AF_UNIX);
67 DCHECK_NE(ERR_IO_PENDING, rv);
68 if (rv != OK)
69 return rv;
70
71 rv = listen_socket_->Bind(address);
72 DCHECK_NE(ERR_IO_PENDING, rv);
73 if (rv != OK) {
74 PLOG(ERROR)
75 << "Could not bind unix domain socket to " << unix_domain_path
76 << (use_abstract_namespace_ ? " (with abstract namespace)" : "");
77 return rv;
78 }
79
80 return listen_socket_->Listen(backlog);
81 }
82
83 int UnixDomainServerSocket::GetLocalAddress(IPEndPoint* address) const {
84 NOTIMPLEMENTED();
85 return ERR_NOT_IMPLEMENTED;
86 }
87
88 int UnixDomainServerSocket::Accept(scoped_ptr<StreamSocket>* socket,
89 const CompletionCallback& callback) {
90 DCHECK(socket);
91 DCHECK(!callback.is_null());
92 DCHECK(listen_socket_);
93 DCHECK(!accept_socket_);
94
95 while (true) {
96 int rv = listen_socket_->Accept(
97 &accept_socket_,
98 base::Bind(&UnixDomainServerSocket::AcceptCompleted,
99 base::Unretained(this), socket, callback));
100 if (rv != OK)
101 return rv;
102 if (AuthenticateAndGetStreamSocket(socket))
103 return OK;
104 }
105 }
106
107 void UnixDomainServerSocket::AcceptCompleted(scoped_ptr<StreamSocket>* socket,
108 const CompletionCallback& callback,
109 int rv) {
110 if (rv != OK) {
111 callback.Run(rv);
112 return;
113 }
114
115 if (AuthenticateAndGetStreamSocket(socket)) {
116 callback.Run(OK);
117 return;
118 }
119
120 // Accept another socket because authentication error should be transparent
121 // to the caller.
mmenke 2014/07/23 18:52:41 optional: May want to duplicate this comment at t
byungchul 2014/07/23 22:27:11 Done.
122 rv = Accept(socket, callback);
123 if (rv != ERR_IO_PENDING)
124 callback.Run(rv);
125 }
126
127 bool UnixDomainServerSocket::AuthenticateAndGetStreamSocket(
128 scoped_ptr<StreamSocket>* socket) {
129 DCHECK(accept_socket_);
130
131 uid_t user_id;
132 gid_t group_id;
133 if (!GetPeerIds(accept_socket_->socket_fd(), &user_id, &group_id) ||
134 !auth_callback_.Run(user_id, group_id)) {
135 accept_socket_.reset();
136 return false;
137 }
138
139 socket->reset(new UnixDomainClientSocket(accept_socket_.Pass()));
140 return true;
141 }
142
143 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698