Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Toggle main menu visibility
Loading...
Searching...
No Matches
RealmSocket.cpp
Go to the documentation of this file.
1
/*
2
* This file is part of Project SkyFire https://www.projectskyfire.org.
3
* See LICENSE.md file for Copyright information
4
*/
5
6
#include "
Log.h
"
7
#include "
Network/BoostAsioUtils.h
"
8
#include "
RealmSocket.h
"
9
#include <boost/asio/buffer.hpp>
10
#include <boost/asio/error.hpp>
11
#include <boost/asio/post.hpp>
12
#include <boost/asio/write.hpp>
13
#include <algorithm>
14
#include <cstring>
15
#include <string>
16
#include <utility>
17
18
namespace
19
{
20
std::string GetAuthOpcodeNameForLogging(
uint8
opcode)
21
{
22
switch
(opcode)
23
{
24
case
0x00:
25
return
"AUTH_LOGON_CHALLENGE"
;
26
case
0x01:
27
return
"AUTH_LOGON_PROOF"
;
28
case
0x02:
29
return
"AUTH_RECONNECT_CHALLENGE"
;
30
case
0x03:
31
return
"AUTH_RECONNECT_PROOF"
;
32
case
0x10:
33
return
"REALM_LIST"
;
34
case
0x32:
35
return
"XFER_ACCEPT"
;
36
case
0x33:
37
return
"XFER_RESUME"
;
38
case
0x34:
39
return
"XFER_CANCEL"
;
40
default
:
41
return
"UNKNOWN_AUTH_OPCODE"
;
42
}
43
}
44
}
45
46
RealmSocket::Session::Session
(
void
) { }
47
48
RealmSocket::Session::~Session
(
void
) { }
49
50
RealmSocket::RealmSocket
(std::unique_ptr<RealmSocketHandle> socket, std::string remoteAddress,
uint16
remotePort) :
51
_socket
(std::move(socket)),
_readBuffer
(),
_inputBuffer
(),
_inputReadPos
(0),
_session
(),
52
_remoteAddress
(std::move(remoteAddress)),
_packetLogAccountName
(),
_remotePort
(remotePort),
_writeQueue
(),
53
_writeInProgress
(false),
_closed
(false),
_closeNotified
(false)
54
{
55
_inputBuffer
.reserve(4096);
56
}
57
58
RealmSocket::~RealmSocket
(
void
)
59
{
60
CloseSocket
();
61
}
62
63
void
RealmSocket::Start
()
64
{
65
if
(
_session
)
66
_session
->OnAccept();
67
68
AsyncRead
();
69
}
70
71
void
RealmSocket::Close
()
72
{
73
CloseSocket
();
74
}
75
76
const
std::string&
RealmSocket::getRemoteAddress
(
void
)
const
77
{
78
return
_remoteAddress
;
79
}
80
81
uint16
RealmSocket::getRemotePort
(
void
)
const
82
{
83
return
_remotePort
;
84
}
85
86
void
RealmSocket::SetPacketLogAccountName
(std::string accountName)
87
{
88
_packetLogAccountName
= std::move(accountName);
89
sPacketLogServer
->RefreshSessionInfo(
this
,
BuildPacketLogSessionInfo
());
90
}
91
92
size_t
RealmSocket::GetAvailableBytes
(
void
)
const
93
{
94
return
_inputBuffer
.size() -
_inputReadPos
;
95
}
96
97
bool
RealmSocket::PeekBytes
(
void
* buf,
size_t
len,
size_t
offset)
const
98
{
99
if
(len == 0)
100
return
true
;
101
102
if
(buf == NULL)
103
return
false
;
104
105
size_t
availableBytes =
GetAvailableBytes
();
106
if
(offset > availableBytes || len > availableBytes - offset)
107
return
false
;
108
109
memcpy(buf,
_inputBuffer
.data() +
_inputReadPos
+ offset, len);
110
return
true
;
111
}
112
113
bool
RealmSocket::ReadBytes
(
void
* buf,
size_t
len)
114
{
115
bool
ret =
PeekBytes
(buf, len);
116
117
if
(ret)
118
DiscardBytes
(len);
119
120
return
ret;
121
}
122
123
void
RealmSocket::DiscardBytes
(
size_t
len)
124
{
125
_inputReadPos
= std::min(
_inputReadPos
+ len,
_inputBuffer
.size());
126
}
127
128
bool
RealmSocket::QueueSend
(
void
const
* buf,
size_t
len)
129
{
130
if
(buf == NULL || len == 0)
131
return
true
;
132
133
if
(
_closed
)
134
return
false
;
135
136
char
const
* bytes =
static_cast<
char
const*
>
(buf);
137
std::vector<char> data(bytes, bytes + len);
138
LogAuthPacket
(data.data(), data.size(),
Skyfire::PACKET_LOG_SERVER_TO_CLIENT
);
139
140
std::shared_ptr<RealmSocket> self = shared_from_this();
141
boost::asio::post(
_socket
->get_executor(),
142
[self, data = std::move(data)]()
mutable
143
{
144
self->QueueWrite(std::move(data));
145
});
146
147
return
true
;
148
}
149
150
void
RealmSocket::set_session
(std::unique_ptr<Session> session)
151
{
152
_session
= std::move(session);
153
}
154
155
void
RealmSocket::Run
()
156
{
157
AsyncRead
();
158
}
159
160
void
RealmSocket::AsyncRead
()
161
{
162
if
(
_closed
|| !
IsOpen
())
163
return
;
164
165
std::shared_ptr<RealmSocket> self = shared_from_this();
166
_socket
->async_read_some(boost::asio::buffer(
_readBuffer
),
167
[self](boost::system::error_code
const
& error,
size_t
bytesTransferred)
168
{
169
self->HandleRead(error, bytesTransferred);
170
});
171
}
172
173
void
RealmSocket::HandleRead
(boost::system::error_code
const
& error,
size_t
bytesTransferred)
174
{
175
if
(error || bytesTransferred == 0)
176
{
177
CloseSocket
();
178
return
;
179
}
180
181
_inputBuffer
.insert(
_inputBuffer
.end(),
_readBuffer
.data(),
_readBuffer
.data() + bytesTransferred);
182
LogAuthPacket
(
_readBuffer
.data(), bytesTransferred,
Skyfire::PACKET_LOG_CLIENT_TO_SERVER
);
183
184
if
(
_session
)
185
{
186
_session
->OnRead();
187
CompactInputBuffer
();
188
}
189
190
if
(!
_closed
)
191
AsyncRead
();
192
}
193
194
void
RealmSocket::QueueWrite
(std::vector<char> data)
195
{
196
if
(
_closed
|| !
IsOpen
())
197
return
;
198
199
bool
startWrite = !
_writeInProgress
&&
_writeQueue
.empty();
200
_writeQueue
.push_back(std::move(data));
201
202
if
(startWrite)
203
StartAsyncWrite
();
204
}
205
206
void
RealmSocket::StartAsyncWrite
()
207
{
208
if
(
_closed
||
_writeInProgress
||
_writeQueue
.empty() || !
IsOpen
())
209
return
;
210
211
_writeInProgress
=
true
;
212
213
std::shared_ptr<RealmSocket> self = shared_from_this();
214
boost::asio::async_write(*
_socket
, boost::asio::buffer(
_writeQueue
.front()),
215
[self](boost::system::error_code
const
& error,
size_t
)
216
{
217
self->HandleWrite(error);
218
});
219
}
220
221
void
RealmSocket::HandleWrite
(boost::system::error_code
const
& error)
222
{
223
if
(!
_writeQueue
.empty())
224
_writeQueue
.pop_front();
225
226
_writeInProgress
=
false
;
227
228
if
(error)
229
{
230
if
(error != boost::asio::error::operation_aborted)
231
{
232
SF_LOG_DEBUG
(
"server.authserver"
,
"Socket send failed for %s:%u with error %d"
,
233
_remoteAddress
.c_str(),
_remotePort
, error.value());
234
}
235
236
CloseSocket
();
237
return
;
238
}
239
240
if
(!
_writeQueue
.empty())
241
StartAsyncWrite
();
242
}
243
244
bool
RealmSocket::IsOpen
(
void
)
const
245
{
246
return
_socket
&&
_socket
->is_open();
247
}
248
249
void
RealmSocket::CloseSocket
()
250
{
251
bool
expected =
false
;
252
if
(!
_closed
.compare_exchange_strong(expected,
true
))
253
return
;
254
255
if
(
IsOpen
())
256
Skyfire::Net::CloseTcpSocket
(*
_socket
);
257
258
NotifyClose
();
259
}
260
261
void
RealmSocket::NotifyClose
()
262
{
263
bool
expected =
false
;
264
if
(!
_closeNotified
.compare_exchange_strong(expected,
true
))
265
return
;
266
267
if
(
_session
)
268
_session
->OnClose();
269
270
sPacketLogServer
->CloseSession(
this
);
271
}
272
273
void
RealmSocket::CompactInputBuffer
()
274
{
275
if
(
_inputReadPos
== 0)
276
return
;
277
278
if
(
_inputReadPos
>=
_inputBuffer
.size())
279
_inputBuffer
.clear();
280
else
281
_inputBuffer
.erase(
_inputBuffer
.begin(),
_inputBuffer
.begin() + ptrdiff_t(
_inputReadPos
));
282
283
_inputReadPos
= 0;
284
}
285
286
Skyfire::PacketLogServerSessionInfo
RealmSocket::BuildPacketLogSessionInfo
()
const
287
{
288
Skyfire::PacketLogServerSessionInfo
sessionInfo;
289
sessionInfo.
RemoteAddress
=
_remoteAddress
;
290
sessionInfo.
AccountName
=
_packetLogAccountName
;
291
sessionInfo.
SessionName
=
"auth"
;
292
sessionInfo.
FilePrefix
=
"authsession"
;
293
return
sessionInfo;
294
}
295
296
void
RealmSocket::LogAuthPacket
(
void
const
* data,
size_t
len,
Skyfire::PacketLogServerDirection
direction)
297
{
298
if
(!
sPacketLogServer
->CanLogPacket())
299
return
;
300
301
uint32
opcode = 0;
302
if
(data && len > 0)
303
opcode = *
static_cast<
uint8
const*
>
(data);
304
305
sPacketLogServer
->LogPacket(
this
,
BuildPacketLogSessionInfo
(), direction, opcode,
306
GetAuthOpcodeNameForLogging(
uint8
(opcode)), data, len);
307
}
BoostAsioUtils.h
uint8
std::uint8_t uint8
Definition
Define.h:79
uint32
std::uint32_t uint32
Definition
Define.h:77
uint16
std::uint16_t uint16
Definition
Define.h:78
Log.h
SF_LOG_DEBUG
#define SF_LOG_DEBUG(filterType__,...)
Definition
Log.h:134
sPacketLogServer
#define sPacketLogServer
Definition
PacketLogServer.h:95
RealmSocket.h
RealmSocket::Session::Session
Session(void)
Definition
RealmSocket.cpp:46
RealmSocket::Session::~Session
virtual ~Session(void)
Definition
RealmSocket.cpp:48
RealmSocket::_packetLogAccountName
std::string _packetLogAccountName
Definition
RealmSocket.h:76
RealmSocket::_inputReadPos
size_t _inputReadPos
Definition
RealmSocket.h:73
RealmSocket::LogAuthPacket
void LogAuthPacket(void const *data, size_t len, Skyfire::PacketLogServerDirection direction)
Definition
RealmSocket.cpp:296
RealmSocket::PeekBytes
bool PeekBytes(void *buf, size_t len, size_t offset=0) const
Definition
RealmSocket.cpp:97
RealmSocket::HandleRead
void HandleRead(boost::system::error_code const &error, size_t bytesTransferred)
Definition
RealmSocket.cpp:173
RealmSocket::_writeQueue
std::deque< std::vector< char > > _writeQueue
Definition
RealmSocket.h:78
RealmSocket::IsOpen
bool IsOpen(void) const
Definition
RealmSocket.cpp:244
RealmSocket::_session
std::unique_ptr< Session > _session
Definition
RealmSocket.h:74
RealmSocket::getRemotePort
uint16 getRemotePort(void) const
Definition
RealmSocket.cpp:81
RealmSocket::GetAvailableBytes
size_t GetAvailableBytes(void) const
Definition
RealmSocket.cpp:92
RealmSocket::ReadBytes
bool ReadBytes(void *buf, size_t len)
Definition
RealmSocket.cpp:113
RealmSocket::CloseSocket
void CloseSocket()
Definition
RealmSocket.cpp:249
RealmSocket::_writeInProgress
bool _writeInProgress
Definition
RealmSocket.h:79
RealmSocket::RealmSocket
RealmSocket(std::unique_ptr< RealmSocketHandle > socket, std::string remoteAddress, uint16 remotePort)
Definition
RealmSocket.cpp:50
RealmSocket::set_session
void set_session(std::unique_ptr< Session > session)
Definition
RealmSocket.cpp:150
RealmSocket::Start
void Start()
Definition
RealmSocket.cpp:63
RealmSocket::_remoteAddress
std::string _remoteAddress
Definition
RealmSocket.h:75
RealmSocket::Close
void Close()
Definition
RealmSocket.cpp:71
RealmSocket::BuildPacketLogSessionInfo
Skyfire::PacketLogServerSessionInfo BuildPacketLogSessionInfo() const
Definition
RealmSocket.cpp:286
RealmSocket::getRemoteAddress
const std::string & getRemoteAddress(void) const
Definition
RealmSocket.cpp:76
RealmSocket::_inputBuffer
std::vector< char > _inputBuffer
Definition
RealmSocket.h:72
RealmSocket::DiscardBytes
void DiscardBytes(size_t len)
Definition
RealmSocket.cpp:123
RealmSocket::QueueSend
bool QueueSend(void const *buf, size_t len)
Definition
RealmSocket.cpp:128
RealmSocket::_closeNotified
std::atomic< bool > _closeNotified
Definition
RealmSocket.h:81
RealmSocket::_closed
std::atomic< bool > _closed
Definition
RealmSocket.h:80
RealmSocket::_readBuffer
std::array< char, 4096 > _readBuffer
Definition
RealmSocket.h:71
RealmSocket::CompactInputBuffer
void CompactInputBuffer()
Definition
RealmSocket.cpp:273
RealmSocket::AsyncRead
void AsyncRead()
Definition
RealmSocket.cpp:160
RealmSocket::~RealmSocket
~RealmSocket(void)
Definition
RealmSocket.cpp:58
RealmSocket::Run
void Run()
Definition
RealmSocket.cpp:155
RealmSocket::_socket
std::unique_ptr< RealmSocketHandle > _socket
Definition
RealmSocket.h:70
RealmSocket::SetPacketLogAccountName
void SetPacketLogAccountName(std::string accountName)
Definition
RealmSocket.cpp:86
RealmSocket::HandleWrite
void HandleWrite(boost::system::error_code const &error)
Definition
RealmSocket.cpp:221
RealmSocket::QueueWrite
void QueueWrite(std::vector< char > data)
Definition
RealmSocket.cpp:194
RealmSocket::StartAsyncWrite
void StartAsyncWrite()
Definition
RealmSocket.cpp:206
RealmSocket::_remotePort
uint16 _remotePort
Definition
RealmSocket.h:77
RealmSocket::NotifyClose
void NotifyClose()
Definition
RealmSocket.cpp:261
Skyfire::Net::CloseTcpSocket
void CloseTcpSocket(boost::asio::ip::tcp::socket &socket)
Definition
BoostAsioUtils.h:45
Skyfire::PacketLogServerDirection
PacketLogServerDirection
Definition
PacketLogServer.h:22
Skyfire::PACKET_LOG_SERVER_TO_CLIENT
@ PACKET_LOG_SERVER_TO_CLIENT
Definition
PacketLogServer.h:24
Skyfire::PACKET_LOG_CLIENT_TO_SERVER
@ PACKET_LOG_CLIENT_TO_SERVER
Definition
PacketLogServer.h:23
Skyfire::PacketLogServerSessionInfo
Definition
PacketLogServer.h:28
Skyfire::PacketLogServerSessionInfo::AccountName
std::string AccountName
Definition
PacketLogServer.h:33
Skyfire::PacketLogServerSessionInfo::RemoteAddress
std::string RemoteAddress
Definition
PacketLogServer.h:31
Skyfire::PacketLogServerSessionInfo::FilePrefix
std::string FilePrefix
Definition
PacketLogServer.h:37
Skyfire::PacketLogServerSessionInfo::SessionName
std::string SessionName
Definition
PacketLogServer.h:36
src
server
authserver
Server
RealmSocket.cpp
Generated on
for Project SkyFire Core by
1.17.0