-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathsocket_manager.hpp
106 lines (97 loc) · 4.72 KB
/
socket_manager.hpp
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <unordered_map>
#include "defination.hpp"
#include "socket.hpp"
#include "tcb_manager.hpp"
namespace mstack {
class socket_manager {
private:
socket_manager() = default;
~socket_manager() = default;
std::unordered_map<uint16_t, std::shared_ptr<socket_t>> sockets;
std::unordered_map<uint16_t, std::shared_ptr<listener_t>> listeners;
public:
socket_manager(const socket_manager&) = delete;
socket_manager(socket_manager&&) = delete;
socket_manager& operator=(const socket_manager&) = delete;
socket_manager& operator=(socket_manager&&) = delete;
static socket_manager& instance() {
static socket_manager instance;
return instance;
}
int register_socket(int proto, ipv4_addr_t ipv4_addr, port_addr_t port_addr) {
for (int i = 1; i < 65535; i++) {
if (sockets.find(i) == sockets.end()) {
ipv4_port_t local_info = {.ipv4_addr = ipv4_addr,
.port_addr = port_addr};
std::shared_ptr<socket_t> socket = std::make_shared<socket_t>();
socket->proto = proto;
socket->local_info = local_info;
sockets[i] = socket;
return i;
}
}
return -1;
}
int listen(int fd) {
if (sockets.find(fd) == sockets.end()) {
return -1;
}
std::shared_ptr<listener_t> listener = std::make_shared<listener_t>();
listener->local_info = sockets[fd]->local_info;
listener->proto = sockets[fd]->proto;
listener->state = SOCKET_CONNECTING;
listener->fd = fd;
listeners[fd] = listener;
auto& tcb_manager = tcb_manager::instance();
tcb_manager.listen_port(listener->local_info.value(), listener);
return 0;
};
int accept(int fd) {
if (listeners.find(fd) == listeners.end()) {
return -1;
}
while (listeners[fd]->acceptors->empty()) {
};
for (int i = 1; i < 65535; i++) {
if (sockets.find(i) == sockets.end()) {
std::optional<std::shared_ptr<tcb_t>> tcb =
listeners[fd]->acceptors->pop_front();
std::shared_ptr<socket_t> socket = std::make_shared<socket_t>();
socket->local_info = tcb.value()->local_info;
socket->remote_info = tcb.value()->remote_info;
socket->proto = listeners[fd]->proto;
socket->state = SOCKET_CONNECTED;
socket->tcb = tcb;
socket->fd = i;
sockets[i] = socket;
return i;
}
}
return -1;
}
int read(int fd, char* buf, int& len) {
if (sockets.find(fd) == sockets.end()) {
len = 0;
return -1;
}
std::shared_ptr<socket_t> socket = sockets[fd];
while (socket->tcb.value()->receive_queue.empty()) {
};
raw_packet r_packet =
std::move(socket->tcb.value()->receive_queue.pop_front().value());
r_packet.buffer->export_data(reinterpret_cast<uint8_t*>(buf), len);
return 0;
}
int write(int fd, char* buf, int& len) {
if (sockets.find(fd) == sockets.end()) {
return -1;
}
std::shared_ptr<socket_t> socket = sockets[fd];
std::unique_ptr<base_packet> out_buffer =
std::make_unique<base_packet>(reinterpret_cast<uint8_t*>(buf), len);
raw_packet r_packet = {.buffer = std::move(out_buffer)};
socket->tcb.value()->send_queue.push_back(std::move(r_packet));
return 0;
}
};
}; // namespace mstack