Skip to content

Commit 112a6ad

Browse files
authored
Cache client IP in RemoteClient so it can always be retrieved (#10887)
specifically: after the peer has already disappeared
1 parent 6e0e032 commit 112a6ad

6 files changed

Lines changed: 84 additions & 99 deletions

File tree

src/clientiface.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,6 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
452452
case CSE_Hello:
453453
m_state = CS_HelloSent;
454454
break;
455-
case CSE_InitLegacy:
456-
m_state = CS_AwaitingInit2;
457-
break;
458455
case CSE_Disconnect:
459456
m_state = CS_Disconnecting;
460457
break;

src/clientiface.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2525
#include "serialization.h" // for SER_FMT_VER_INVALID
2626
#include "network/networkpacket.h"
2727
#include "network/networkprotocol.h"
28+
#include "network/address.h"
2829
#include "porting.h"
2930

3031
#include <list>
@@ -188,7 +189,6 @@ enum ClientStateEvent
188189
{
189190
CSE_Hello,
190191
CSE_AuthAccept,
191-
CSE_InitLegacy,
192192
CSE_GotInit2,
193193
CSE_SetDenied,
194194
CSE_SetDefinitionsSent,
@@ -338,17 +338,24 @@ class RemoteClient
338338
u8 getMajor() const { return m_version_major; }
339339
u8 getMinor() const { return m_version_minor; }
340340
u8 getPatch() const { return m_version_patch; }
341-
const std::string &getFull() const { return m_full_version; }
341+
const std::string &getFullVer() const { return m_full_version; }
342342

343343
void setLangCode(const std::string &code) { m_lang_code = code; }
344344
const std::string &getLangCode() const { return m_lang_code; }
345+
346+
void setCachedAddress(const Address &addr) { m_addr = addr; }
347+
const Address &getAddress() const { return m_addr; }
348+
345349
private:
346350
// Version is stored in here after INIT before INIT2
347351
u8 m_pending_serialization_version = SER_FMT_VER_INVALID;
348352

349353
/* current state of client */
350354
ClientState m_state = CS_Created;
351-
355+
356+
// Cached here so retrieval doesn't have to go to connection API
357+
Address m_addr;
358+
352359
// Client sent language code
353360
std::string m_lang_code;
354361

@@ -412,7 +419,7 @@ class RemoteClient
412419

413420
/*
414421
client information
415-
*/
422+
*/
416423
u8 m_version_major = 0;
417424
u8 m_version_minor = 0;
418425
u8 m_version_patch = 0;

src/network/serverpackethandler.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
5656
session_t peer_id = pkt->getPeerId();
5757
RemoteClient *client = getClient(peer_id, CS_Created);
5858

59+
Address addr;
5960
std::string addr_s;
6061
try {
61-
Address address = getPeerAddress(peer_id);
62-
addr_s = address.serializeString();
63-
}
64-
catch (con::PeerNotFoundException &e) {
62+
addr = m_con->GetPeerAddress(peer_id);
63+
addr_s = addr.serializeString();
64+
} catch (con::PeerNotFoundException &e) {
6565
/*
6666
* no peer for this packet found
6767
* most common reason is peer timeout, e.g. peer didn't
@@ -73,13 +73,14 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
7373
return;
7474
}
7575

76-
// If net_proto_version is set, this client has already been handled
7776
if (client->getState() > CS_Created) {
7877
verbosestream << "Server: Ignoring multiple TOSERVER_INITs from " <<
7978
addr_s << " (peer_id=" << peer_id << ")" << std::endl;
8079
return;
8180
}
8281

82+
client->setCachedAddress(addr);
83+
8384
verbosestream << "Server: Got TOSERVER_INIT from " << addr_s <<
8485
" (peer_id=" << peer_id << ")" << std::endl;
8586

src/script/lua_api/l_server.cpp

Lines changed: 40 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -116,24 +116,18 @@ int ModApiServer::l_get_player_privs(lua_State *L)
116116
int ModApiServer::l_get_player_ip(lua_State *L)
117117
{
118118
NO_MAP_LOCK_REQUIRED;
119-
const char * name = luaL_checkstring(L, 1);
120-
RemotePlayer *player = dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name);
121-
if(player == NULL)
122-
{
119+
120+
Server *server = getServer(L);
121+
122+
const char *name = luaL_checkstring(L, 1);
123+
RemotePlayer *player = server->getEnv().getPlayer(name);
124+
if (!player) {
123125
lua_pushnil(L); // no such player
124126
return 1;
125127
}
126-
try
127-
{
128-
Address addr = getServer(L)->getPeerAddress(player->getPeerId());
129-
std::string ip_str = addr.serializeString();
130-
lua_pushstring(L, ip_str.c_str());
131-
return 1;
132-
} catch (const con::PeerNotFoundException &) {
133-
dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
134-
lua_pushnil(L); // error
135-
return 1;
136-
}
128+
129+
lua_pushstring(L, server->getPeerAddress(player->getPeerId()).serializeString().c_str());
130+
return 1;
137131
}
138132

139133
// get_player_information(name)
@@ -150,26 +144,18 @@ int ModApiServer::l_get_player_information(lua_State *L)
150144
return 1;
151145
}
152146

153-
Address addr;
154-
try {
155-
addr = server->getPeerAddress(player->getPeerId());
156-
} catch (const con::PeerNotFoundException &) {
157-
dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
158-
lua_pushnil(L); // error
159-
return 1;
160-
}
161-
162-
float min_rtt, max_rtt, avg_rtt, min_jitter, max_jitter, avg_jitter;
163-
ClientState state;
164-
u32 uptime;
165-
u16 prot_vers;
166-
u8 ser_vers, major, minor, patch;
167-
std::string vers_string, lang_code;
147+
/*
148+
Be careful not to introduce a depdendency on the connection to
149+
the peer here. This function is >>REQUIRED<< to still be able to return
150+
values even when the peer unexpectedly disappears.
151+
Hence all the ConInfo values here are optional.
152+
*/
168153

169154
auto getConInfo = [&] (con::rtt_stat_type type, float *value) -> bool {
170155
return server->getClientConInfo(player->getPeerId(), type, value);
171156
};
172157

158+
float min_rtt, max_rtt, avg_rtt, min_jitter, max_jitter, avg_jitter;
173159
bool have_con_info =
174160
getConInfo(con::MIN_RTT, &min_rtt) &&
175161
getConInfo(con::MAX_RTT, &max_rtt) &&
@@ -178,11 +164,9 @@ int ModApiServer::l_get_player_information(lua_State *L)
178164
getConInfo(con::MAX_JITTER, &max_jitter) &&
179165
getConInfo(con::AVG_JITTER, &avg_jitter);
180166

181-
bool r = server->getClientInfo(player->getPeerId(), &state, &uptime,
182-
&ser_vers, &prot_vers, &major, &minor, &patch, &vers_string,
183-
&lang_code);
184-
if (!r) {
185-
dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
167+
ClientInfo info;
168+
if (!server->getClientInfo(player->getPeerId(), info)) {
169+
warningstream << FUNCTION_NAME << ": no client info?!" << std::endl;
186170
lua_pushnil(L); // error
187171
return 1;
188172
}
@@ -191,13 +175,13 @@ int ModApiServer::l_get_player_information(lua_State *L)
191175
int table = lua_gettop(L);
192176

193177
lua_pushstring(L,"address");
194-
lua_pushstring(L, addr.serializeString().c_str());
178+
lua_pushstring(L, info.addr.serializeString().c_str());
195179
lua_settable(L, table);
196180

197181
lua_pushstring(L,"ip_version");
198-
if (addr.getFamily() == AF_INET) {
182+
if (info.addr.getFamily() == AF_INET) {
199183
lua_pushnumber(L, 4);
200-
} else if (addr.getFamily() == AF_INET6) {
184+
} else if (info.addr.getFamily() == AF_INET6) {
201185
lua_pushnumber(L, 6);
202186
} else {
203187
lua_pushnumber(L, 0);
@@ -231,44 +215,44 @@ int ModApiServer::l_get_player_information(lua_State *L)
231215
}
232216

233217
lua_pushstring(L,"connection_uptime");
234-
lua_pushnumber(L, uptime);
218+
lua_pushnumber(L, info.uptime);
235219
lua_settable(L, table);
236220

237221
lua_pushstring(L,"protocol_version");
238-
lua_pushnumber(L, prot_vers);
222+
lua_pushnumber(L, info.prot_vers);
239223
lua_settable(L, table);
240224

241225
lua_pushstring(L, "formspec_version");
242226
lua_pushnumber(L, player->formspec_version);
243227
lua_settable(L, table);
244228

245229
lua_pushstring(L, "lang_code");
246-
lua_pushstring(L, lang_code.c_str());
230+
lua_pushstring(L, info.lang_code.c_str());
247231
lua_settable(L, table);
248232

249233
#ifndef NDEBUG
250234
lua_pushstring(L,"serialization_version");
251-
lua_pushnumber(L, ser_vers);
235+
lua_pushnumber(L, info.ser_vers);
252236
lua_settable(L, table);
253237

254238
lua_pushstring(L,"major");
255-
lua_pushnumber(L, major);
239+
lua_pushnumber(L, info.major);
256240
lua_settable(L, table);
257241

258242
lua_pushstring(L,"minor");
259-
lua_pushnumber(L, minor);
243+
lua_pushnumber(L, info.minor);
260244
lua_settable(L, table);
261245

262246
lua_pushstring(L,"patch");
263-
lua_pushnumber(L, patch);
247+
lua_pushnumber(L, info.patch);
264248
lua_settable(L, table);
265249

266250
lua_pushstring(L,"version_string");
267-
lua_pushstring(L, vers_string.c_str());
251+
lua_pushstring(L, info.vers_string.c_str());
268252
lua_settable(L, table);
269253

270254
lua_pushstring(L,"state");
271-
lua_pushstring(L,ClientInterface::state2Name(state).c_str());
255+
lua_pushstring(L, ClientInterface::state2Name(info.state).c_str());
272256
lua_settable(L, table);
273257
#endif
274258

@@ -296,23 +280,18 @@ int ModApiServer::l_get_ban_description(lua_State *L)
296280
int ModApiServer::l_ban_player(lua_State *L)
297281
{
298282
NO_MAP_LOCK_REQUIRED;
299-
const char * name = luaL_checkstring(L, 1);
300-
RemotePlayer *player = dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name);
301-
if (player == NULL) {
283+
284+
Server *server = getServer(L);
285+
286+
const char *name = luaL_checkstring(L, 1);
287+
RemotePlayer *player = server->getEnv().getPlayer(name);
288+
if (!player) {
302289
lua_pushboolean(L, false); // no such player
303290
return 1;
304291
}
305-
try
306-
{
307-
Address addr = getServer(L)->getPeerAddress(
308-
dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name)->getPeerId());
309-
std::string ip_str = addr.serializeString();
310-
getServer(L)->setIpBanned(ip_str, name);
311-
} catch(const con::PeerNotFoundException &) {
312-
dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
313-
lua_pushboolean(L, false); // error
314-
return 1;
315-
}
292+
293+
std::string ip_str = server->getPeerAddress(player->getPeerId()).serializeString();
294+
server->setIpBanned(ip_str, name);
316295
lua_pushboolean(L, true);
317296
return 1;
318297
}

src/server.cpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,20 +1242,8 @@ bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float*
12421242
return *retval != -1;
12431243
}
12441244

1245-
bool Server::getClientInfo(
1246-
session_t peer_id,
1247-
ClientState* state,
1248-
u32* uptime,
1249-
u8* ser_vers,
1250-
u16* prot_vers,
1251-
u8* major,
1252-
u8* minor,
1253-
u8* patch,
1254-
std::string* vers_string,
1255-
std::string* lang_code
1256-
)
1257-
{
1258-
*state = m_clients.getClientState(peer_id);
1245+
bool Server::getClientInfo(session_t peer_id, ClientInfo &ret)
1246+
{
12591247
m_clients.lock();
12601248
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
12611249

@@ -1264,15 +1252,18 @@ bool Server::getClientInfo(
12641252
return false;
12651253
}
12661254

1267-
*uptime = client->uptime();
1268-
*ser_vers = client->serialization_version;
1269-
*prot_vers = client->net_proto_version;
1255+
ret.state = client->getState();
1256+
ret.addr = client->getAddress();
1257+
ret.uptime = client->uptime();
1258+
ret.ser_vers = client->serialization_version;
1259+
ret.prot_vers = client->net_proto_version;
1260+
1261+
ret.major = client->getMajor();
1262+
ret.minor = client->getMinor();
1263+
ret.patch = client->getPatch();
1264+
ret.vers_string = client->getFullVer();
12701265

1271-
*major = client->getMajor();
1272-
*minor = client->getMinor();
1273-
*patch = client->getPatch();
1274-
*vers_string = client->getFull();
1275-
*lang_code = client->getLangCode();
1266+
ret.lang_code = client->getLangCode();
12761267

12771268
m_clients.unlock();
12781269

@@ -3339,7 +3330,8 @@ void Server::hudSetHotbarSelectedImage(RemotePlayer *player, const std::string &
33393330

33403331
Address Server::getPeerAddress(session_t peer_id)
33413332
{
3342-
return m_con->GetPeerAddress(peer_id);
3333+
// Note that this is only set after Init was received in Server::handleCommand_Init
3334+
return getClient(peer_id, CS_Invalid)->getAddress();
33433335
}
33443336

33453337
void Server::setLocalPlayerAnimations(RemotePlayer *player,

src/server.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ struct MinimapMode {
126126
u16 scale = 1;
127127
};
128128

129+
// structure for everything getClientInfo returns, for convenience
130+
struct ClientInfo {
131+
ClientState state;
132+
Address addr;
133+
u32 uptime;
134+
u8 ser_vers;
135+
u16 prot_vers;
136+
u8 major, minor, patch;
137+
std::string vers_string, lang_code;
138+
};
139+
129140
class Server : public con::PeerHandler, public MapEventReceiver,
130141
public IGameDef
131142
{
@@ -326,9 +337,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
326337
void DenyAccess_Legacy(session_t peer_id, const std::wstring &reason);
327338
void DisconnectPeer(session_t peer_id);
328339
bool getClientConInfo(session_t peer_id, con::rtt_stat_type type, float *retval);
329-
bool getClientInfo(session_t peer_id, ClientState *state, u32 *uptime,
330-
u8* ser_vers, u16* prot_vers, u8* major, u8* minor, u8* patch,
331-
std::string* vers_string, std::string* lang_code);
340+
bool getClientInfo(session_t peer_id, ClientInfo &ret);
332341

333342
void printToConsoleOnly(const std::string &text);
334343

0 commit comments

Comments
 (0)