3
3
#include < stdexcept>
4
4
#include < system_error>
5
5
6
+ #include < netinet/in.h>
6
7
#include < sys/socket.h>
7
8
#include < sys/un.h>
8
9
#include < unistd.h>
@@ -11,13 +12,20 @@ namespace vast::server {
11
12
union addr {
12
13
sockaddr base;
13
14
sockaddr_un unix;
15
+ sockaddr_in net;
14
16
};
15
17
16
18
struct descriptor
17
19
{
18
20
int fd;
19
21
20
- explicit descriptor (int fd) : fd(fd) {}
22
+ explicit descriptor () : fd(-1 ) {}
23
+
24
+ explicit descriptor (int fd) : fd(fd) {
25
+ if (fd < 0 ) {
26
+ throw std::system_error (errno, std::generic_category ());
27
+ }
28
+ }
21
29
22
30
descriptor (const descriptor &) = delete ;
23
31
descriptor &operator =(const descriptor &) = delete ;
@@ -53,8 +61,8 @@ namespace vast::server {
53
61
sock_adapter::~sock_adapter () = default ;
54
62
55
63
void sock_adapter::close () {
56
- pimpl->clientd = descriptor{ - 1 };
57
- pimpl->serverd = descriptor{ - 1 };
64
+ pimpl->clientd = descriptor{};
65
+ pimpl->serverd = descriptor{};
58
66
}
59
67
60
68
size_t sock_adapter::read_some (std::span< char > dst) {
@@ -73,15 +81,29 @@ namespace vast::server {
73
81
return static_cast < size_t >(res);
74
82
}
75
83
84
+ static descriptor bind_and_accept (
85
+ descriptor &serverd, addr &sockaddr_server, size_t socklen_server,
86
+ sockaddr *sockaddr_client, socklen_t *socklen_client
87
+ ) {
88
+ int rc = bind (serverd, &sockaddr_server.base , static_cast < socklen_t >(socklen_server));
89
+ if (rc < 0 ) {
90
+ throw std::system_error (errno, std::generic_category ());
91
+ }
92
+
93
+ rc = listen (serverd, 1 );
94
+ if (rc < 0 ) {
95
+ throw std::system_error (errno, std::generic_category ());
96
+ }
97
+
98
+ return descriptor{ accept (serverd, sockaddr_client, socklen_client) };
99
+ }
100
+
76
101
std::unique_ptr< sock_adapter > sock_adapter::create_unix_socket (const std::string &path) {
77
102
if (path.size () > (sizeof (sockaddr_un::sun_path) - 1 )) {
78
103
throw std::runtime_error (" Unix socket pathname is too long" );
79
104
}
80
105
81
106
descriptor serverd{ socket (AF_UNIX, SOCK_STREAM, 0 ) };
82
- if (serverd < 0 ) {
83
- throw std::system_error (errno, std::generic_category ());
84
- }
85
107
86
108
addr sock_addr{};
87
109
sock_addr.unix .sun_family = AF_UNIX;
@@ -95,18 +117,29 @@ namespace vast::server {
95
117
if (unlink (path.c_str ()) < 0 && errno != ENOENT) {
96
118
throw std::system_error (errno, std::generic_category ());
97
119
}
98
- int rc =
99
- bind (serverd, &sock_addr.base , static_cast < socklen_t >(SUN_LEN (&sock_addr.unix )));
100
- if (rc < 0 ) {
101
- throw std::system_error (errno, std::generic_category ());
102
- }
103
120
104
- rc = listen (serverd, 1 );
105
- if (rc < 0 ) {
106
- throw std::system_error (errno, std::generic_category ());
107
- }
121
+ auto clientd =
122
+ bind_and_accept (serverd, sock_addr, sizeof (sock_addr.unix ), nullptr , nullptr );
123
+
124
+ return std::unique_ptr< sock_adapter >(new sock_adapter{
125
+ std::make_unique< impl >(std::move (serverd), std::move (clientd)) });
126
+ }
127
+
128
+ std::unique_ptr< sock_adapter >
129
+ sock_adapter::create_tcp_server_socket (uint32_t host, uint16_t port) {
130
+ descriptor serverd{ socket (AF_INET, SOCK_STREAM, 0 ) };
131
+
132
+ addr sock_addr{};
133
+ sock_addr.net .sin_family = AF_INET;
134
+ sock_addr.net .sin_addr .s_addr = htonl (host);
135
+ sock_addr.net .sin_port = htons (port);
136
+
137
+ addr client_addr{};
138
+ socklen_t client_addr_size = sizeof (client_addr.net );
108
139
109
- descriptor clientd{ accept (serverd, nullptr , nullptr ) };
140
+ auto clientd = bind_and_accept (
141
+ serverd, sock_addr, sizeof (sock_addr.net ), &client_addr.base , &client_addr_size
142
+ );
110
143
111
144
return std::unique_ptr< sock_adapter >(new sock_adapter{
112
145
std::make_unique< impl >(std::move (serverd), std::move (clientd)) });
0 commit comments