forked from e2guardian/e2guardian
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSocketArray.cpp
165 lines (145 loc) · 4.42 KB
/
SocketArray.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// SocketArray - wrapper for clean handling of an array of Sockets
// For all support, instructions and copyright go to:
// http://e2guardian.org/
// Released under the GPL v2, with the OpenSSL exception described in the README file.
// INCLUDES
#ifdef HAVE_CONFIG_H
#include "e2config.h"
#endif
#include "SocketArray.hpp"
#include "Queue.hpp"
#include <syslog.h>
#include <cerrno>
#include <cstring>
// GLOBALS
extern bool is_daemonised;
extern thread_local std::string thread_id;
// IMPLEMENTATION
SocketArray::~SocketArray()
{
delete[] drawer;
}
void SocketArray::deleteAll()
{
delete[] drawer;
drawer = NULL;
socknum = 0;
}
// close all sockets & create new ones
void SocketArray::reset(int sockcount)
{
delete[] drawer;
drawer = new Socket[sockcount];
socknum = sockcount;
}
// bind our first socket to any IP
int SocketArray::bindSingle(int port)
{
if (socknum < 1) {
return -1;
}
#ifdef E2DEBUG
std::cerr << thread_id << "bindSingle binding port" << port << std::endl;
#endif
lc_types.push_back(CT_PROXY);
return drawer[0].bind(port);
}
int SocketArray::bindSingle(unsigned int index, int port, unsigned int type)
{
if (socknum <= index) {
return -1;
}
#ifdef E2DEBUG
std::cerr << thread_id << "bindSingle binding port" << port << " with type " << type << std::endl;
#endif
lc_types.push_back(type);
return drawer[index].bind(port);
}
// bind our first socket to any IP and one or more ports
int SocketArray::bindSingleM(std::deque<String> &ports)
{
if (socknum < ports.size()) {
return -1;
}
for (unsigned int i = 0; i < ports.size(); i++) {
#ifdef E2DEBUG
std::cerr << thread_id << "bindSingleM binding port" << ports[i] << std::endl;
#endif
if (drawer[i].bind(ports[i].toInteger())) {
if (!is_daemonised) {
std::cerr << thread_id << "Error binding server socket: ["
<< ports[i] << " " << i << "] (" << strerror(errno) << ")" << std::endl;
}
String p = ports[i];
syslog(LOG_ERR, "Error binding socket: [%s %d] (%s)", p.toCharArray(), i, strerror(errno));
return -1;
}
lc_types.push_back(CT_PROXY);
}
return 0;
}
// return an array of our socket FDs
int *SocketArray::getFDAll()
{
int *fds = new int[socknum];
for (unsigned int i = 0; i < socknum; i++) {
#ifdef E2DEBUG
std::cerr << thread_id << "Socket " << i << " fd:" << drawer[i].getFD() << std::endl;
#endif
fds[i] = drawer[i].getFD();
}
return fds;
}
// listen on all IPs with given kernel queue size
int SocketArray::listenAll(int queue)
{
for (unsigned int i = 0; i < socknum; i++) {
if (drawer[i].listen(queue)) {
if (!is_daemonised) {
std::cerr << thread_id << "Error listening to socket" << std::endl;
}
syslog(LOG_ERR, "%s", "Error listening to socket");
return -1;
}
}
return 0;
}
// bind all sockets to given IP list
int SocketArray::bindAll(std::deque<String> &ips, std::deque<String> &ports)
{
if (ips.size() > socknum) {
return -1;
}
//for (unsigned int i = 0; i < socknum; i++) {
for (unsigned int i = 0; i < ips.size(); i++) {
#ifdef E2DEBUG
std::cerr << thread_id << "Binding server socket[" << ports[i] << " " << ips[i] << " " << i << "])" << std::endl;
#endif
if (drawer[i].bind(ips[i].toCharArray(), ports[i].toInteger())) {
if (!is_daemonised) {
std::cerr << thread_id << "Error binding server socket: ["
<< ports[i] << " " << ips[i] << " " << i << "] (" << strerror(errno) << ")" << std::endl;
}
syslog(LOG_ERR, "Error binding socket: [%s %s %d] (%s)", ports[i].toCharArray(), ips[i].toCharArray(), i, strerror(errno));
return -1;
}
lc_types.push_back(CT_PROXY);
}
return 0;
}
// try connecting to all our sockets which are still open to allow tidy close
void SocketArray::self_connect() {
for (unsigned int i = 0; i < socknum; i++) {
if (drawer[i].getFD() > -1) {
std::string sip = drawer[i].getLocalIP();
int port = drawer[i].getPort();
Socket temp;
temp.setTimeout(100);
temp.connect(sip, port);
temp.close();
}
}
}
unsigned int SocketArray::getType(unsigned int ind) {
return lc_types.at(ind);
}