-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtcp_listener.cc
83 lines (65 loc) · 2.58 KB
/
tcp_listener.cc
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
/*
* Copyright (C) 2022 SKTT1Ryze. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under License.
* */
#include <arpa/inet.h>
#include <string.h>
#include "kuro.h"
TcpListener::TcpListener() {
int fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd < 0) throw std::runtime_error("socket(2) return value less than zero");
sockfd = fd;
}
TcpListener::TcpListener(int sockfd) : sockfd(sockfd) {}
TcpListener::~TcpListener() { close(sockfd); }
void TcpListener::set_reuseaddr(bool reuseaddr) {
int opt = reuseaddr ? 1 : 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt,
sizeof(opt)) < 0)
throw std::runtime_error("set_reuseaddr error");
}
void TcpListener::set_reuseport(bool reuseport) {
int opt = reuseport ? 1 : 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const void*)&opt,
sizeof(opt)) < 0)
throw std::runtime_error("set_reuseport error");
}
void TcpListener::bind_socket(const char* ip_addr,
unsigned short int sin_port) {
struct in_addr sin_addr;
if (inet_aton(ip_addr, &sin_addr) == 0)
throw std::runtime_error("ip address error");
addr.sin_family = AF_INET;
addr.sin_addr = sin_addr;
addr.sin_port = sin_port;
bzero(&(addr.sin_zero), sizeof(addr.sin_zero));
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) == -1)
throw std::runtime_error("bind(2) return -1");
return;
}
void TcpListener::listen_socket(int backlog) {
if (listen(sockfd, backlog) == -1)
throw std::runtime_error("listen(2) return -1");
}
Map<__s32, Accept, int> TcpListener::async_accept(
std::shared_ptr<io_uring>& uring, TcpStream* stream_) {
auto accept = Accept(uring, sockfd, &stream_->addr, &stream_->len, 0);
int* stream_fd_ptr = &stream_->fd;
auto map = Map<__s32, Accept, int>(std::move(accept),
[stream_fd_ptr](__s32 fd) -> int {
*stream_fd_ptr = (int)fd;
return (int)fd;
});
return map;
}