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

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: Moved UnixDomainListenSocket to net::deprecated namespace. 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 // Accept another socket because authentication error should be transparent
105 // to the caller.
106 }
107 }
108
109 void UnixDomainServerSocket::AcceptCompleted(scoped_ptr<StreamSocket>* socket,
110 const CompletionCallback& callback,
111 int rv) {
112 if (rv != OK) {
113 callback.Run(rv);
114 return;
115 }
116
117 if (AuthenticateAndGetStreamSocket(socket)) {
118 callback.Run(OK);
119 return;
120 }
121
122 // Accept another socket because authentication error should be transparent
123 // to the caller.
124 rv = Accept(socket, callback);
125 if (rv != ERR_IO_PENDING)
126 callback.Run(rv);
127 }
128
129 bool UnixDomainServerSocket::AuthenticateAndGetStreamSocket(
130 scoped_ptr<StreamSocket>* socket) {
131 DCHECK(accept_socket_);
132
133 uid_t user_id;
134 gid_t group_id;
135 if (!GetPeerIds(accept_socket_->socket_fd(), &user_id, &group_id) ||
136 !auth_callback_.Run(user_id, group_id)) {
137 accept_socket_.reset();
138 return false;
139 }
140
141 socket->reset(new UnixDomainClientSocket(accept_socket_.Pass()));
142 return true;
143 }
144
145 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/unix_domain_server_socket_posix.h ('k') | net/socket/unix_domain_server_socket_posix_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698