-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSocket.cpp
86 lines (75 loc) · 2.59 KB
/
Socket.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// SPDX-License-Identifier: MIT
#include <absl/status/statusor.h>
#include <absl/strings/str_format.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <Socket.hpp>
namespace ffkx {
namespace net {
absl::Status Socket::SetRxBufferSize(size_t size) {
int fd = GetRawFd();
int sz = size;
int err = setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));
if (err < 0) {
return absl::ErrnoToStatus(errno, absl::StrFormat("Failed to set SO_RCVBUFFORCE option size (%d).", sz));
}
return absl::OkStatus();
}
absl::Status Socket::SetTxBufferSize(size_t size) {
int fd = GetRawFd();
int sz = size;
int err = setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &sz, sizeof(sz));
if (err < 0) {
return absl::ErrnoToStatus(errno, absl::StrFormat("Failed to set SO_SNDBUFFORCE option size (%d).", sz));
}
return absl::OkStatus();
}
absl::Status Socket::BindAny(int port) {
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(port);
int err = bind(GetRawFd(), reinterpret_cast<struct sockaddr *>(&server_addr), sizeof(server_addr));
if (err < 0) {
return absl::ErrnoToStatus(errno, absl::StrFormat("Failed to bind socket to port %d.", port));
}
return absl::OkStatus();
}
absl::Status Socket::SetListen(int backlog) {
int err = listen(GetRawFd(), backlog);
if (err < 0) {
return absl::ErrnoToStatus(errno, "Failed to listen on the TCP socket.");
}
return absl::OkStatus();
}
absl::StatusOr<io::FileDescriptor> Socket::AcceptConnection() {
int accept_fd = accept4(GetRawFd(), nullptr, nullptr, SOCK_CLOEXEC | SOCK_NONBLOCK);
if (accept_fd < 0) {
return absl::ErrnoToStatus(errno, "Failed to accept connection from socket.");
}
return io::FileDescriptor(accept_fd);
}
absl::StatusOr<Socket> Socket::MakeTCP() {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
return absl::ErrnoToStatus(errno, "Failed to create TCP stream socket.");
}
io::FileDescriptor fd(server_fd);
int opt = 1;
int err = setsockopt(fd.GetRawFd(), IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
if (err < 0) {
return absl::ErrnoToStatus(errno, "Failed to set TCP_NODELAY option.");
}
int optval = 1;
err = setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
if (err < 0) {
return absl::ErrnoToStatus(errno, "Failed to set SO_REUSEPORT option.");
}
return Socket(std::move(fd));
}
} // namespace net
} // namespace ffkx