1 // Copyright 2022 gRPC Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "test/core/event_engine/posix/posix_engine_test_utils.h"
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <poll.h>
20 #include <stdlib.h>
21 #include <sys/socket.h>
22
23 #include "absl/log/log.h"
24 #include "absl/strings/str_format.h"
25 #include "src/core/util/crash.h"
26
27 namespace grpc_event_engine {
28 namespace experimental {
29
30 using ResolvedAddress =
31 grpc_event_engine::experimental::EventEngine::ResolvedAddress;
32
33 // Creates a client socket and blocks until it connects to the specified
34 // server address. The function abort fails upon encountering errors.
ConnectToServerOrDie(const ResolvedAddress & server_address)35 int ConnectToServerOrDie(const ResolvedAddress& server_address) {
36 int client_fd;
37 int one = 1;
38 int flags;
39
40 client_fd = socket(AF_INET6, SOCK_STREAM, 0);
41 setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
42 // Make fd non-blocking.
43 flags = fcntl(client_fd, F_GETFL, 0);
44 fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
45
46 if (connect(client_fd, const_cast<struct sockaddr*>(server_address.address()),
47 server_address.size()) == -1) {
48 if (errno == EINPROGRESS) {
49 struct pollfd pfd;
50 pfd.fd = client_fd;
51 pfd.events = POLLOUT;
52 pfd.revents = 0;
53 if (poll(&pfd, 1, -1) == -1) {
54 LOG(ERROR) << "poll() failed during connect; errno=" << errno;
55 abort();
56 }
57 } else {
58 grpc_core::Crash(
59 absl::StrFormat("Failed to connect to the server (errno=%d)", errno));
60 }
61 }
62 return client_fd;
63 }
64
65 } // namespace experimental
66 } // namespace grpc_event_engine
67