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/strings/str_format.h"
24
25 #include <grpc/support/log.h>
26
27 #include "src/core/lib/gprpp/crash.h"
28
29 namespace grpc_event_engine {
30 namespace experimental {
31
32 using ResolvedAddress =
33 grpc_event_engine::experimental::EventEngine::ResolvedAddress;
34
35 // Creates a client socket and blocks until it connects to the specified
36 // server address. The function abort fails upon encountering errors.
ConnectToServerOrDie(const ResolvedAddress & server_address)37 int ConnectToServerOrDie(const ResolvedAddress& server_address) {
38 int client_fd;
39 int one = 1;
40 int flags;
41
42 client_fd = socket(AF_INET6, SOCK_STREAM, 0);
43 setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
44 // Make fd non-blocking.
45 flags = fcntl(client_fd, F_GETFL, 0);
46 fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
47
48 if (connect(client_fd, const_cast<struct sockaddr*>(server_address.address()),
49 server_address.size()) == -1) {
50 if (errno == EINPROGRESS) {
51 struct pollfd pfd;
52 pfd.fd = client_fd;
53 pfd.events = POLLOUT;
54 pfd.revents = 0;
55 if (poll(&pfd, 1, -1) == -1) {
56 gpr_log(GPR_ERROR, "poll() failed during connect; errno=%d", errno);
57 abort();
58 }
59 } else {
60 grpc_core::Crash(
61 absl::StrFormat("Failed to connect to the server (errno=%d)", errno));
62 }
63 }
64 return client_fd;
65 }
66
67 } // namespace experimental
68 } // namespace grpc_event_engine
69