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.
5 #include "net/socket/unix_domain_client_socket_posix.h"
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/posix/eintr_wrapper.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/socket/socket_libevent.h"
18 #include "net/socket/unix_domain_server_socket_posix.h"
19 #include "testing/gtest/include/gtest/gtest.h"
24 const char kSocketFilename
[] = "socket_for_testing";
26 bool UserCanConnectCallback(
27 bool allow_user
, const UnixDomainServerSocket::Credentials
& credentials
) {
28 // Here peers are running in same process.
29 #if defined(OS_LINUX) || defined(OS_ANDROID)
30 EXPECT_EQ(getpid(), credentials
.process_id
);
32 EXPECT_EQ(getuid(), credentials
.user_id
);
33 EXPECT_EQ(getgid(), credentials
.group_id
);
37 UnixDomainServerSocket::AuthCallback
CreateAuthCallback(bool allow_user
) {
38 return base::Bind(&UserCanConnectCallback
, allow_user
);
41 // Connects socket synchronously.
42 int ConnectSynchronously(StreamSocket
* socket
) {
43 TestCompletionCallback connect_callback
;
44 int rv
= socket
->Connect(connect_callback
.callback());
45 if (rv
== ERR_IO_PENDING
)
46 rv
= connect_callback
.WaitForResult();
50 // Reads data from |socket| until it fills |buf| at least up to |min_data_len|.
51 // Returns length of data read, or a net error.
52 int ReadSynchronously(StreamSocket
* socket
,
56 DCHECK_LE(min_data_len
, buf_len
);
57 scoped_refptr
<DrainableIOBuffer
> read_buf(
58 new DrainableIOBuffer(buf
, buf_len
));
59 TestCompletionCallback read_callback
;
60 // Iterate reading several times (but not infinite) until it reads at least
61 // |min_data_len| bytes into |buf|.
62 for (int retry_count
= 10;
63 retry_count
> 0 && (read_buf
->BytesConsumed() < min_data_len
||
64 // Try at least once when min_data_len == 0.
67 int rv
= socket
->Read(
68 read_buf
.get(), read_buf
->BytesRemaining(), read_callback
.callback());
69 EXPECT_GE(read_buf
->BytesRemaining(), rv
);
70 if (rv
== ERR_IO_PENDING
) {
71 // If |min_data_len| is 0, returns ERR_IO_PENDING to distinguish the case
72 // when some data has been read.
73 if (min_data_len
== 0) {
74 // No data has been read because of for-loop condition.
75 DCHECK_EQ(0, read_buf
->BytesConsumed());
76 return ERR_IO_PENDING
;
78 rv
= read_callback
.WaitForResult();
80 EXPECT_NE(ERR_IO_PENDING
, rv
);
83 read_buf
->DidConsume(rv
);
85 EXPECT_LE(0, read_buf
->BytesRemaining());
86 return read_buf
->BytesConsumed();
89 // Writes data to |socket| until it completes writing |buf| up to |buf_len|.
90 // Returns length of data written, or a net error.
91 int WriteSynchronously(StreamSocket
* socket
,
94 scoped_refptr
<DrainableIOBuffer
> write_buf(
95 new DrainableIOBuffer(buf
, buf_len
));
96 TestCompletionCallback write_callback
;
97 // Iterate writing several times (but not infinite) until it writes buf fully.
98 for (int retry_count
= 10;
99 retry_count
> 0 && write_buf
->BytesRemaining() > 0;
101 int rv
= socket
->Write(write_buf
.get(),
102 write_buf
->BytesRemaining(),
103 write_callback
.callback());
104 EXPECT_GE(write_buf
->BytesRemaining(), rv
);
105 if (rv
== ERR_IO_PENDING
)
106 rv
= write_callback
.WaitForResult();
107 EXPECT_NE(ERR_IO_PENDING
, rv
);
110 write_buf
->DidConsume(rv
);
112 EXPECT_LE(0, write_buf
->BytesRemaining());
113 return write_buf
->BytesConsumed();
116 class UnixDomainClientSocketTest
: public testing::Test
{
118 UnixDomainClientSocketTest() {
119 EXPECT_TRUE(temp_dir_
.CreateUniqueTempDir());
120 socket_path_
= temp_dir_
.path().Append(kSocketFilename
).value();
123 base::ScopedTempDir temp_dir_
;
124 std::string socket_path_
;
127 TEST_F(UnixDomainClientSocketTest
, Connect
) {
128 const bool kUseAbstractNamespace
= false;
130 UnixDomainServerSocket
server_socket(CreateAuthCallback(true),
131 kUseAbstractNamespace
);
132 EXPECT_EQ(OK
, server_socket
.ListenWithAddressAndPort(socket_path_
, 0, 1));
134 scoped_ptr
<StreamSocket
> accepted_socket
;
135 TestCompletionCallback accept_callback
;
136 EXPECT_EQ(ERR_IO_PENDING
,
137 server_socket
.Accept(&accepted_socket
, accept_callback
.callback()));
138 EXPECT_FALSE(accepted_socket
);
140 UnixDomainClientSocket
client_socket(socket_path_
, kUseAbstractNamespace
);
141 EXPECT_FALSE(client_socket
.IsConnected());
143 EXPECT_EQ(OK
, ConnectSynchronously(&client_socket
));
144 EXPECT_TRUE(client_socket
.IsConnected());
145 // Server has not yet been notified of the connection.
146 EXPECT_FALSE(accepted_socket
);
148 EXPECT_EQ(OK
, accept_callback
.WaitForResult());
149 EXPECT_TRUE(accepted_socket
);
150 EXPECT_TRUE(accepted_socket
->IsConnected());
153 TEST_F(UnixDomainClientSocketTest
, ConnectWithSocketDescriptor
) {
154 const bool kUseAbstractNamespace
= false;
156 UnixDomainServerSocket
server_socket(CreateAuthCallback(true),
157 kUseAbstractNamespace
);
158 EXPECT_EQ(OK
, server_socket
.ListenWithAddressAndPort(socket_path_
, 0, 1));
160 SocketDescriptor accepted_socket_fd
= kInvalidSocket
;
161 TestCompletionCallback accept_callback
;
162 EXPECT_EQ(ERR_IO_PENDING
,
163 server_socket
.AcceptSocketDescriptor(&accepted_socket_fd
,
164 accept_callback
.callback()));
165 EXPECT_EQ(kInvalidSocket
, accepted_socket_fd
);
167 UnixDomainClientSocket
client_socket(socket_path_
, kUseAbstractNamespace
);
168 EXPECT_FALSE(client_socket
.IsConnected());
170 EXPECT_EQ(OK
, ConnectSynchronously(&client_socket
));
171 EXPECT_TRUE(client_socket
.IsConnected());
172 // Server has not yet been notified of the connection.
173 EXPECT_EQ(kInvalidSocket
, accepted_socket_fd
);
175 EXPECT_EQ(OK
, accept_callback
.WaitForResult());
176 EXPECT_NE(kInvalidSocket
, accepted_socket_fd
);
178 SocketDescriptor client_socket_fd
= client_socket
.ReleaseConnectedSocket();
179 EXPECT_NE(kInvalidSocket
, client_socket_fd
);
181 // Now, re-wrap client_socket_fd in a UnixDomainClientSocket and try a read
182 // to be sure it hasn't gotten accidentally closed.
183 SockaddrStorage addr
;
184 ASSERT_TRUE(UnixDomainClientSocket::FillAddress(socket_path_
, false, &addr
));
185 scoped_ptr
<SocketLibevent
> adopter(new SocketLibevent
);
186 adopter
->AdoptConnectedSocket(client_socket_fd
, addr
);
187 UnixDomainClientSocket
rewrapped_socket(adopter
.Pass());
188 EXPECT_TRUE(rewrapped_socket
.IsConnected());
191 const int kReadDataSize
= 10;
192 scoped_refptr
<IOBuffer
> read_buffer(new IOBuffer(kReadDataSize
));
193 TestCompletionCallback read_callback
;
194 EXPECT_EQ(ERR_IO_PENDING
,
195 rewrapped_socket
.Read(
196 read_buffer
.get(), kReadDataSize
, read_callback
.callback()));
198 EXPECT_EQ(0, IGNORE_EINTR(close(accepted_socket_fd
)));
201 TEST_F(UnixDomainClientSocketTest
, ConnectWithAbstractNamespace
) {
202 const bool kUseAbstractNamespace
= true;
204 UnixDomainClientSocket
client_socket(socket_path_
, kUseAbstractNamespace
);
205 EXPECT_FALSE(client_socket
.IsConnected());
207 #if defined(OS_ANDROID) || defined(OS_LINUX)
208 UnixDomainServerSocket
server_socket(CreateAuthCallback(true),
209 kUseAbstractNamespace
);
210 EXPECT_EQ(OK
, server_socket
.ListenWithAddressAndPort(socket_path_
, 0, 1));
212 scoped_ptr
<StreamSocket
> accepted_socket
;
213 TestCompletionCallback accept_callback
;
214 EXPECT_EQ(ERR_IO_PENDING
,
215 server_socket
.Accept(&accepted_socket
, accept_callback
.callback()));
216 EXPECT_FALSE(accepted_socket
);
218 EXPECT_EQ(OK
, ConnectSynchronously(&client_socket
));
219 EXPECT_TRUE(client_socket
.IsConnected());
220 // Server has not yet beend notified of the connection.
221 EXPECT_FALSE(accepted_socket
);
223 EXPECT_EQ(OK
, accept_callback
.WaitForResult());
224 EXPECT_TRUE(accepted_socket
);
225 EXPECT_TRUE(accepted_socket
->IsConnected());
227 EXPECT_EQ(ERR_ADDRESS_INVALID
, ConnectSynchronously(&client_socket
));
231 TEST_F(UnixDomainClientSocketTest
, ConnectToNonExistentSocket
) {
232 const bool kUseAbstractNamespace
= false;
234 UnixDomainClientSocket
client_socket(socket_path_
, kUseAbstractNamespace
);
235 EXPECT_FALSE(client_socket
.IsConnected());
236 EXPECT_EQ(ERR_FILE_NOT_FOUND
, ConnectSynchronously(&client_socket
));
239 TEST_F(UnixDomainClientSocketTest
,
240 ConnectToNonExistentSocketWithAbstractNamespace
) {
241 const bool kUseAbstractNamespace
= true;
243 UnixDomainClientSocket
client_socket(socket_path_
, kUseAbstractNamespace
);
244 EXPECT_FALSE(client_socket
.IsConnected());
246 TestCompletionCallback connect_callback
;
247 #if defined(OS_ANDROID) || defined(OS_LINUX)
248 EXPECT_EQ(ERR_CONNECTION_REFUSED
, ConnectSynchronously(&client_socket
));
250 EXPECT_EQ(ERR_ADDRESS_INVALID
, ConnectSynchronously(&client_socket
));
254 TEST_F(UnixDomainClientSocketTest
, DisconnectFromClient
) {
255 UnixDomainServerSocket
server_socket(CreateAuthCallback(true), false);
256 EXPECT_EQ(OK
, server_socket
.ListenWithAddressAndPort(socket_path_
, 0, 1));
257 scoped_ptr
<StreamSocket
> accepted_socket
;
258 TestCompletionCallback accept_callback
;
259 EXPECT_EQ(ERR_IO_PENDING
,
260 server_socket
.Accept(&accepted_socket
, accept_callback
.callback()));
261 UnixDomainClientSocket
client_socket(socket_path_
, false);
262 EXPECT_EQ(OK
, ConnectSynchronously(&client_socket
));
264 EXPECT_EQ(OK
, accept_callback
.WaitForResult());
265 EXPECT_TRUE(accepted_socket
->IsConnected());
266 EXPECT_TRUE(client_socket
.IsConnected());
269 const int kReadDataSize
= 10;
270 scoped_refptr
<IOBuffer
> read_buffer(new IOBuffer(kReadDataSize
));
271 TestCompletionCallback read_callback
;
272 EXPECT_EQ(ERR_IO_PENDING
,
273 accepted_socket
->Read(
274 read_buffer
.get(), kReadDataSize
, read_callback
.callback()));
276 // Disconnect from client side.
277 client_socket
.Disconnect();
278 EXPECT_FALSE(client_socket
.IsConnected());
279 EXPECT_FALSE(accepted_socket
->IsConnected());
281 // Connection closed by peer.
282 EXPECT_EQ(0 /* EOF */, read_callback
.WaitForResult());
283 // Note that read callback won't be called when the connection is closed
284 // locally before the peer closes it. SocketLibevent just clears callbacks.
287 TEST_F(UnixDomainClientSocketTest
, DisconnectFromServer
) {
288 UnixDomainServerSocket
server_socket(CreateAuthCallback(true), false);
289 EXPECT_EQ(OK
, server_socket
.ListenWithAddressAndPort(socket_path_
, 0, 1));
290 scoped_ptr
<StreamSocket
> accepted_socket
;
291 TestCompletionCallback accept_callback
;
292 EXPECT_EQ(ERR_IO_PENDING
,
293 server_socket
.Accept(&accepted_socket
, accept_callback
.callback()));
294 UnixDomainClientSocket
client_socket(socket_path_
, false);
295 EXPECT_EQ(OK
, ConnectSynchronously(&client_socket
));
297 EXPECT_EQ(OK
, accept_callback
.WaitForResult());
298 EXPECT_TRUE(accepted_socket
->IsConnected());
299 EXPECT_TRUE(client_socket
.IsConnected());
302 const int kReadDataSize
= 10;
303 scoped_refptr
<IOBuffer
> read_buffer(new IOBuffer(kReadDataSize
));
304 TestCompletionCallback read_callback
;
305 EXPECT_EQ(ERR_IO_PENDING
,
307 read_buffer
.get(), kReadDataSize
, read_callback
.callback()));
309 // Disconnect from server side.
310 accepted_socket
->Disconnect();
311 EXPECT_FALSE(accepted_socket
->IsConnected());
312 EXPECT_FALSE(client_socket
.IsConnected());
314 // Connection closed by peer.
315 EXPECT_EQ(0 /* EOF */, read_callback
.WaitForResult());
316 // Note that read callback won't be called when the connection is closed
317 // locally before the peer closes it. SocketLibevent just clears callbacks.
320 TEST_F(UnixDomainClientSocketTest
, ReadAfterWrite
) {
321 UnixDomainServerSocket
server_socket(CreateAuthCallback(true), false);
322 EXPECT_EQ(OK
, server_socket
.ListenWithAddressAndPort(socket_path_
, 0, 1));
323 scoped_ptr
<StreamSocket
> accepted_socket
;
324 TestCompletionCallback accept_callback
;
325 EXPECT_EQ(ERR_IO_PENDING
,
326 server_socket
.Accept(&accepted_socket
, accept_callback
.callback()));
327 UnixDomainClientSocket
client_socket(socket_path_
, false);
328 EXPECT_EQ(OK
, ConnectSynchronously(&client_socket
));
330 EXPECT_EQ(OK
, accept_callback
.WaitForResult());
331 EXPECT_TRUE(accepted_socket
->IsConnected());
332 EXPECT_TRUE(client_socket
.IsConnected());
334 // Send data from client to server.
335 const int kWriteDataSize
= 10;
336 scoped_refptr
<IOBuffer
> write_buffer(
337 new StringIOBuffer(std::string(kWriteDataSize
, 'd')));
340 WriteSynchronously(&client_socket
, write_buffer
.get(), kWriteDataSize
));
342 // The buffer is bigger than write data size.
343 const int kReadBufferSize
= kWriteDataSize
* 2;
344 scoped_refptr
<IOBuffer
> read_buffer(new IOBuffer(kReadBufferSize
));
345 EXPECT_EQ(kWriteDataSize
,
346 ReadSynchronously(accepted_socket
.get(),
350 EXPECT_EQ(std::string(write_buffer
->data(), kWriteDataSize
),
351 std::string(read_buffer
->data(), kWriteDataSize
));
353 // Send data from server and client.
354 EXPECT_EQ(kWriteDataSize
,
356 accepted_socket
.get(), write_buffer
.get(), kWriteDataSize
));
358 // Read multiple times.
359 const int kSmallReadBufferSize
= kWriteDataSize
/ 3;
360 EXPECT_EQ(kSmallReadBufferSize
,
361 ReadSynchronously(&client_socket
,
363 kSmallReadBufferSize
,
364 kSmallReadBufferSize
));
365 EXPECT_EQ(std::string(write_buffer
->data(), kSmallReadBufferSize
),
366 std::string(read_buffer
->data(), kSmallReadBufferSize
));
368 EXPECT_EQ(kWriteDataSize
- kSmallReadBufferSize
,
369 ReadSynchronously(&client_socket
,
372 kWriteDataSize
- kSmallReadBufferSize
));
373 EXPECT_EQ(std::string(write_buffer
->data() + kSmallReadBufferSize
,
374 kWriteDataSize
- kSmallReadBufferSize
),
375 std::string(read_buffer
->data(),
376 kWriteDataSize
- kSmallReadBufferSize
));
381 ReadSynchronously(&client_socket
, read_buffer
.get(), kReadBufferSize
, 0));
383 // Disconnect from server side after read-write.
384 accepted_socket
->Disconnect();
385 EXPECT_FALSE(accepted_socket
->IsConnected());
386 EXPECT_FALSE(client_socket
.IsConnected());
389 TEST_F(UnixDomainClientSocketTest
, ReadBeforeWrite
) {
390 UnixDomainServerSocket
server_socket(CreateAuthCallback(true), false);
391 EXPECT_EQ(OK
, server_socket
.ListenWithAddressAndPort(socket_path_
, 0, 1));
392 scoped_ptr
<StreamSocket
> accepted_socket
;
393 TestCompletionCallback accept_callback
;
394 EXPECT_EQ(ERR_IO_PENDING
,
395 server_socket
.Accept(&accepted_socket
, accept_callback
.callback()));
396 UnixDomainClientSocket
client_socket(socket_path_
, false);
397 EXPECT_EQ(OK
, ConnectSynchronously(&client_socket
));
399 EXPECT_EQ(OK
, accept_callback
.WaitForResult());
400 EXPECT_TRUE(accepted_socket
->IsConnected());
401 EXPECT_TRUE(client_socket
.IsConnected());
403 // Wait for data from client.
404 const int kWriteDataSize
= 10;
405 const int kReadBufferSize
= kWriteDataSize
* 2;
406 const int kSmallReadBufferSize
= kWriteDataSize
/ 3;
407 // Read smaller than write data size first.
408 scoped_refptr
<IOBuffer
> read_buffer(new IOBuffer(kReadBufferSize
));
409 TestCompletionCallback read_callback
;
412 accepted_socket
->Read(
413 read_buffer
.get(), kSmallReadBufferSize
, read_callback
.callback()));
415 scoped_refptr
<IOBuffer
> write_buffer(
416 new StringIOBuffer(std::string(kWriteDataSize
, 'd')));
419 WriteSynchronously(&client_socket
, write_buffer
.get(), kWriteDataSize
));
421 // First read completed.
422 int rv
= read_callback
.WaitForResult();
424 EXPECT_LE(rv
, kSmallReadBufferSize
);
426 // Read remaining data.
427 const int kExpectedRemainingDataSize
= kWriteDataSize
- rv
;
428 EXPECT_LE(0, kExpectedRemainingDataSize
);
429 EXPECT_EQ(kExpectedRemainingDataSize
,
430 ReadSynchronously(accepted_socket
.get(),
433 kExpectedRemainingDataSize
));
435 EXPECT_EQ(ERR_IO_PENDING
,
437 accepted_socket
.get(), read_buffer
.get(), kReadBufferSize
, 0));
439 // Disconnect from server side after read-write.
440 accepted_socket
->Disconnect();
441 EXPECT_FALSE(accepted_socket
->IsConnected());
442 EXPECT_FALSE(client_socket
.IsConnected());