Skip to content

Commit fbd1768

Browse files
committed
(socket+websocket+http+redis+snake servers) expose the remote ip and remote port when a new connection is made (see #222) / only ipv4 is handled
1 parent 3a67357 commit fbd1768

26 files changed

+147
-49
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ set( IXWEBSOCKET_SOURCES
5858
set( IXWEBSOCKET_HEADERS
5959
ixwebsocket/IXBench.h
6060
ixwebsocket/IXCancellationRequest.h
61+
ixwebsocket/IXConnectionInfo.h
6162
ixwebsocket/IXConnectionState.h
6263
ixwebsocket/IXDNSLookup.h
6364
ixwebsocket/IXExponentialBackoff.h

docs/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22
All changes to this project will be documented in this file.
33

4+
## [9.9.0] - 2020-07-08
5+
6+
(socket+websocket+http+redis+snake servers) expose the remote ip and remote port when a new connection is made
7+
48
## [9.8.6] - 2020-07-06
59

610
(cmake) change the way zlib and openssl are searched

docs/usage.md

+14-8
Original file line numberDiff line numberDiff line change
@@ -257,28 +257,31 @@ ix::WebSocketServer server(port);
257257

258258
server.setOnConnectionCallback(
259259
[&server](std::shared_ptr<WebSocket> webSocket,
260-
std::shared_ptr<ConnectionState> connectionState)
260+
std::shared_ptr<ConnectionState> connectionState,
261+
std::unique_ptr<ConnectionInfo> connectionInfo)
261262
{
263+
std::cout << "Remote ip: " << connectionInfo->remoteIp << std::endl;
264+
262265
webSocket->setOnMessageCallback(
263266
[webSocket, connectionState, &server](const ix::WebSocketMessagePtr msg)
264267
{
265268
if (msg->type == ix::WebSocketMessageType::Open)
266269
{
267-
std::cerr << "New connection" << std::endl;
270+
std::cout << "New connection" << std::endl;
268271

269272
// A connection state object is available, and has a default id
270273
// You can subclass ConnectionState and pass an alternate factory
271274
// to override it. It is useful if you want to store custom
272275
// attributes per connection (authenticated bool flag, attributes, etc...)
273-
std::cerr << "id: " << connectionState->getId() << std::endl;
276+
std::cout << "id: " << connectionState->getId() << std::endl;
274277

275278
// The uri the client did connect to.
276-
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
279+
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
277280

278-
std::cerr << "Headers:" << std::endl;
281+
std::cout << "Headers:" << std::endl;
279282
for (auto it : msg->openInfo.headers)
280283
{
281-
std::cerr << it.first << ": " << it.second << std::endl;
284+
std::cout << it.first << ": " << it.second << std::endl;
282285
}
283286
}
284287
else if (msg->type == ix::WebSocketMessageType::Message)
@@ -417,11 +420,14 @@ If you want to handle how requests are processed, implement the setOnConnectionC
417420
```cpp
418421
setOnConnectionCallback(
419422
[this](HttpRequestPtr request,
420-
std::shared_ptr<ConnectionState> /*connectionState*/) -> HttpResponsePtr
423+
std::shared_ptr<ConnectionState> /*connectionState*/,
424+
std::unique_ptr<ConnectionInfo> connectionInfo) -> HttpResponsePtr
421425
{
422426
// Build a string for the response
423427
std::stringstream ss;
424-
ss << request->method
428+
ss << connectionInfo->remoteIp
429+
<< " "
430+
<< request->method
425431
<< " "
426432
<< request->uri;
427433

ixredis/ixredis/IXRedisServer.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@ namespace ix
4545
}
4646

4747
void RedisServer::handleConnection(std::unique_ptr<Socket> socket,
48-
std::shared_ptr<ConnectionState> connectionState)
48+
std::shared_ptr<ConnectionState> connectionState,
49+
std::unique_ptr<ConnectionInfo> connectionInfo)
4950
{
51+
logInfo("New connection from remote ip " + connectionInfo->remoteIp);
52+
5053
_connectedClientsCount++;
5154

5255
while (!_stopHandlingConnections)

ixredis/ixredis/IXRedisServer.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ namespace ix
4444

4545
// Methods
4646
virtual void handleConnection(std::unique_ptr<Socket>,
47-
std::shared_ptr<ConnectionState> connectionState) final;
47+
std::shared_ptr<ConnectionState> connectionState,
48+
std::unique_ptr<ConnectionInfo> connectionInfo) final;
4849
virtual size_t getConnectedClientsCount() final;
4950

5051
bool startsWith(const std::string& str, const std::string& start);

ixsnake/ixsnake/IXSnakeServer.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,19 @@ namespace snake
6161

6262
_server.setOnConnectionCallback(
6363
[this](std::shared_ptr<ix::WebSocket> webSocket,
64-
std::shared_ptr<ix::ConnectionState> connectionState) {
64+
std::shared_ptr<ix::ConnectionState> connectionState,
65+
std::unique_ptr<ix::ConnectionInfo> connectionInfo) {
6566
auto state = std::dynamic_pointer_cast<SnakeConnectionState>(connectionState);
66-
67+
auto remoteIp = connectionInfo->remoteIp;
68+
6769
webSocket->setOnMessageCallback(
68-
[this, webSocket, state](const ix::WebSocketMessagePtr& msg) {
70+
[this, webSocket, state, remoteIp](const ix::WebSocketMessagePtr& msg) {
6971
std::stringstream ss;
7072
ix::LogLevel logLevel = ix::LogLevel::Debug;
7173
if (msg->type == ix::WebSocketMessageType::Open)
7274
{
7375
ss << "New connection" << std::endl;
76+
ss << "remote ip: " << remoteIp << std::endl;
7477
ss << "id: " << state->getId() << std::endl;
7578
ss << "Uri: " << msg->openInfo.uri << std::endl;
7679
ss << "Headers:" << std::endl;

ixwebsocket/IXConnectionInfo.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* IXConnectionInfo.h
3+
* Author: Benjamin Sergeant
4+
* Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
5+
*/
6+
7+
#pragma once
8+
9+
#include <string>
10+
11+
namespace ix
12+
{
13+
struct ConnectionInfo
14+
{
15+
std::string remoteIp;
16+
int remotePort;
17+
18+
ConnectionInfo(const std::string& r = std::string(), int p = 0)
19+
: remoteIp(r)
20+
, remotePort(p)
21+
{
22+
;
23+
}
24+
};
25+
} // namespace ix

ixwebsocket/IXHttpServer.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ namespace ix
115115
}
116116

117117
void HttpServer::handleConnection(std::unique_ptr<Socket> socket,
118-
std::shared_ptr<ConnectionState> connectionState)
118+
std::shared_ptr<ConnectionState> connectionState,
119+
std::unique_ptr<ConnectionInfo> connectionInfo)
119120
{
120121
_connectedClientsCount++;
121122

@@ -124,7 +125,9 @@ namespace ix
124125

125126
if (std::get<0>(ret))
126127
{
127-
auto response = _onConnectionCallback(std::get<2>(ret), connectionState);
128+
auto response = _onConnectionCallback(std::get<2>(ret),
129+
connectionState,
130+
std::move(connectionInfo));
128131
if (!Http::sendResponse(response, socket))
129132
{
130133
logError("Cannot send response");
@@ -144,7 +147,8 @@ namespace ix
144147
{
145148
setOnConnectionCallback(
146149
[this](HttpRequestPtr request,
147-
std::shared_ptr<ConnectionState> /*connectionState*/) -> HttpResponsePtr {
150+
std::shared_ptr<ConnectionState> /*connectionState*/,
151+
std::unique_ptr<ConnectionInfo> connectionInfo) -> HttpResponsePtr {
148152
std::string uri(request->uri);
149153
if (uri.empty() || uri == "/")
150154
{
@@ -174,7 +178,8 @@ namespace ix
174178

175179
// Log request
176180
std::stringstream ss;
177-
ss << request->method << " " << request->headers["User-Agent"] << " "
181+
ss << connectionInfo->remoteIp << ":" << connectionInfo->remotePort << " "
182+
<< request->method << " " << request->headers["User-Agent"] << " "
178183
<< request->uri << " " << content.size();
179184
logInfo(ss.str());
180185

@@ -200,13 +205,15 @@ namespace ix
200205
setOnConnectionCallback(
201206
[this,
202207
redirectUrl](HttpRequestPtr request,
203-
std::shared_ptr<ConnectionState> /*connectionState*/) -> HttpResponsePtr {
208+
std::shared_ptr<ConnectionState> /*connectionState*/,
209+
std::unique_ptr<ConnectionInfo> connectionInfo) -> HttpResponsePtr {
204210
WebSocketHttpHeaders headers;
205211
headers["Server"] = userAgent();
206212

207213
// Log request
208214
std::stringstream ss;
209-
ss << request->method << " " << request->headers["User-Agent"] << " "
215+
ss << connectionInfo->remoteIp << ":" << connectionInfo->remotePort << " "
216+
<< request->method << " " << request->headers["User-Agent"] << " "
210217
<< request->uri;
211218
logInfo(ss.str());
212219

ixwebsocket/IXHttpServer.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ namespace ix
2323
{
2424
public:
2525
using OnConnectionCallback =
26-
std::function<HttpResponsePtr(HttpRequestPtr, std::shared_ptr<ConnectionState>)>;
26+
std::function<HttpResponsePtr(HttpRequestPtr,
27+
std::shared_ptr<ConnectionState>,
28+
std::unique_ptr<ConnectionInfo> connectionInfo)>;
2729

2830
HttpServer(int port = SocketServer::kDefaultPort,
2931
const std::string& host = SocketServer::kDefaultHost,
@@ -44,7 +46,8 @@ namespace ix
4446

4547
// Methods
4648
virtual void handleConnection(std::unique_ptr<Socket>,
47-
std::shared_ptr<ConnectionState> connectionState) final;
49+
std::shared_ptr<ConnectionState> connectionState,
50+
std::unique_ptr<ConnectionInfo> connectionInfo) final;
4851
virtual size_t getConnectedClientsCount() final;
4952

5053
void setDefaultConnectionCallback();

ixwebsocket/IXSocketServer.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ namespace ix
307307
continue;
308308
}
309309

310+
// FIXME error handling
311+
char *remoteIp = inet_ntoa(client.sin_addr);
312+
auto connectionInfo = std::make_unique<ConnectionInfo>(remoteIp, client.sin_port);
313+
310314
std::shared_ptr<ConnectionState> connectionState;
311315
if (_connectionStateFactory)
312316
{
@@ -342,7 +346,7 @@ namespace ix
342346
_connectionsThreads.push_back(std::make_pair(
343347
connectionState,
344348
std::thread(
345-
&SocketServer::handleConnection, this, std::move(socket), connectionState)));
349+
&SocketServer::handleConnection, this, std::move(socket), connectionState, std::move(connectionInfo))));
346350
}
347351
}
348352

ixwebsocket/IXSocketServer.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#pragma once
88

9+
#include "IXConnectionInfo.h"
910
#include "IXConnectionState.h"
1011
#include "IXSocketTLSOptions.h"
1112
#include <atomic>
@@ -102,7 +103,8 @@ namespace ix
102103
ConnectionStateFactory _connectionStateFactory;
103104

104105
virtual void handleConnection(std::unique_ptr<Socket>,
105-
std::shared_ptr<ConnectionState> connectionState) = 0;
106+
std::shared_ptr<ConnectionState> connectionState,
107+
std::unique_ptr<ConnectionInfo> connectionInfo) = 0;
106108
virtual size_t getConnectedClientsCount() = 0;
107109

108110
// Returns true if all connection threads are joined

ixwebsocket/IXWebSocketServer.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,13 @@ namespace ix
7272
}
7373

7474
void WebSocketServer::handleConnection(std::unique_ptr<Socket> socket,
75-
std::shared_ptr<ConnectionState> connectionState)
75+
std::shared_ptr<ConnectionState> connectionState,
76+
std::unique_ptr<ConnectionInfo> connectionInfo)
7677
{
7778
setThreadName("WebSocketServer::" + connectionState->getId());
7879

7980
auto webSocket = std::make_shared<WebSocket>();
80-
_onConnectionCallback(webSocket, connectionState);
81+
_onConnectionCallback(webSocket, connectionState, std::move(connectionInfo));
8182

8283
webSocket->disableAutomaticReconnection();
8384

ixwebsocket/IXWebSocketServer.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ namespace ix
2323
{
2424
public:
2525
using OnConnectionCallback =
26-
std::function<void(std::shared_ptr<WebSocket>, std::shared_ptr<ConnectionState>)>;
26+
std::function<void(std::shared_ptr<WebSocket>, std::shared_ptr<ConnectionState>,
27+
std::unique_ptr<ConnectionInfo> connectionInfo)>;
2728

2829
WebSocketServer(int port = SocketServer::kDefaultPort,
2930
const std::string& host = SocketServer::kDefaultHost,
@@ -60,7 +61,8 @@ namespace ix
6061

6162
// Methods
6263
virtual void handleConnection(std::unique_ptr<Socket> socket,
63-
std::shared_ptr<ConnectionState> connectionState) final;
64+
std::shared_ptr<ConnectionState> connectionState,
65+
std::unique_ptr<ConnectionInfo> connectionInfo);
6466
virtual size_t getConnectedClientsCount() final;
6567
};
6668
} // namespace ix

ixwebsocket/IXWebSocketVersion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66

77
#pragma once
88

9-
#define IX_WEBSOCKET_VERSION "9.8.6"
9+
#define IX_WEBSOCKET_VERSION "9.9.0"

test/IXCobraToSentryBotTest.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,15 @@ TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]")
9595

9696
sentryServer.setOnConnectionCallback(
9797
[](HttpRequestPtr request,
98-
std::shared_ptr<ConnectionState> /*connectionState*/) -> HttpResponsePtr {
98+
std::shared_ptr<ConnectionState> /*connectionState*/,
99+
std::unique_ptr<ConnectionInfo> connectionInfo) -> HttpResponsePtr {
99100
WebSocketHttpHeaders headers;
100101
headers["Server"] = userAgent();
101102

102103
// Log request
103104
std::stringstream ss;
104-
ss << request->method << " " << request->headers["User-Agent"] << " "
105+
ss << connectionInfo->remoteIp << ":" << connectionInfo->remotePort << " "
106+
<< request->method << " " << request->headers["User-Agent"] << " "
105107
<< request->uri;
106108

107109
if (request->method == "POST")

test/IXTest.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,15 @@ namespace ix
8585
bool startWebSocketEchoServer(ix::WebSocketServer& server)
8686
{
8787
server.setOnConnectionCallback([&server](std::shared_ptr<ix::WebSocket> webSocket,
88-
std::shared_ptr<ConnectionState> connectionState) {
88+
std::shared_ptr<ConnectionState> connectionState,
89+
std::unique_ptr<ConnectionInfo> connectionInfo) {
90+
auto remoteIp = connectionInfo->remoteIp;
8991
webSocket->setOnMessageCallback(
90-
[webSocket, connectionState, &server](const ix::WebSocketMessagePtr& msg) {
92+
[webSocket, connectionState, remoteIp, &server](const ix::WebSocketMessagePtr& msg) {
9193
if (msg->type == ix::WebSocketMessageType::Open)
9294
{
9395
TLogger() << "New connection";
96+
TLogger() << "Remote ip: " << remoteIp;
9497
TLogger() << "Uri: " << msg->openInfo.uri;
9598
TLogger() << "Headers:";
9699
for (auto it : msg->openInfo.headers)

test/IXWebSocketBroadcastTest.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,16 @@ namespace
191191

192192
server.setOnConnectionCallback([&server, &connectionId](
193193
std::shared_ptr<ix::WebSocket> webSocket,
194-
std::shared_ptr<ConnectionState> connectionState) {
195-
webSocket->setOnMessageCallback([webSocket, connectionState, &connectionId, &server](
194+
std::shared_ptr<ConnectionState> connectionState,
195+
std::unique_ptr<ConnectionInfo> connectionInfo) {
196+
auto remoteIp = connectionInfo->remoteIp;
197+
webSocket->setOnMessageCallback([webSocket, connectionState, remoteIp, &connectionId, &server](
196198
const ix::WebSocketMessagePtr& msg) {
197199
if (msg->type == ix::WebSocketMessageType::Open)
198200
{
199201
TLogger() << "New connection";
200202
connectionState->computeId();
203+
TLogger() << "remote ip: " << remoteIp;
201204
TLogger() << "id: " << connectionState->getId();
202205
TLogger() << "Uri: " << msg->openInfo.uri;
203206
TLogger() << "Headers:";

test/IXWebSocketChatTest.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,16 @@ namespace
194194
bool startServer(ix::WebSocketServer& server)
195195
{
196196
server.setOnConnectionCallback([&server](std::shared_ptr<ix::WebSocket> webSocket,
197-
std::shared_ptr<ConnectionState> connectionState) {
197+
std::shared_ptr<ConnectionState> connectionState,
198+
199+
std::unique_ptr<ConnectionInfo> connectionInfo) {
200+
auto remoteIp = connectionInfo->remoteIp;
198201
webSocket->setOnMessageCallback(
199-
[webSocket, connectionState, &server](const ix::WebSocketMessagePtr& msg) {
202+
[webSocket, connectionState, remoteIp, &server](const ix::WebSocketMessagePtr& msg) {
200203
if (msg->type == ix::WebSocketMessageType::Open)
201204
{
202205
TLogger() << "New connection";
206+
TLogger() << "remote ip: " << remoteIp;
203207
TLogger() << "id: " << connectionState->getId();
204208
TLogger() << "Uri: " << msg->openInfo.uri;
205209
TLogger() << "Headers:";

0 commit comments

Comments
 (0)