1 /* Copyright (C) 2009, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 - Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15 - Neither the name of the Developers nor the names of its contributors may
16 be used to endorse or promote products derived from this software without
17 specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 void dumpmsg(uint8_t *data, int size);
43 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer, int bufsize)
45 pds_t *pds = Pds_create(buffer, bufsize);
48 Pds_add_numval(pds, msg->messageType);
49 Pds_add_numval(pds, msg->sessionId);
51 switch (msg->messageType) {
53 Pds_add_numval(pds, msg->payload.speex.seq);
54 Pds_append_data_nosize(pds, msg->payload.speex.data, msg->payload.speex.size);
57 Pds_add_string(pds, msg->payload.serverReject.reason);
58 Pds_add_numval(pds, msg->payload.serverReject.type);
61 Pds_add_numval(pds, msg->payload.serverSync.maxBandwidth);
62 Pds_add_string(pds, msg->payload.serverSync.welcomeText);
65 Pds_add_string(pds, msg->payload.serverJoin.playerName);
66 Pds_add_numval(pds, msg->payload.serverJoin.id);
68 case ChannelDescUpdate:
69 Pds_add_numval(pds, msg->payload.channelDescUpdate.id);
70 Pds_add_string(pds, msg->payload.channelDescUpdate.desc);
73 Pds_add_numval(pds, msg->payload.channelAdd.id);
74 Pds_add_numval(pds, msg->payload.channelAdd.parentId);
75 Pds_add_string(pds, msg->payload.channelAdd.name);
78 Pds_add_numval(pds, msg->payload.playerMove.victim);
79 Pds_add_numval(pds, msg->payload.playerMove.channel);
84 Pds_add_numval(pds, msg->payload.ping.timestamp);
87 Pds_add_numval(pds, msg->payload.pingStats.timestamp);
88 Pds_add_numval(pds, msg->payload.pingStats.good);
89 Pds_add_numval(pds, msg->payload.pingStats.late);
90 Pds_add_numval(pds, msg->payload.pingStats.lost);
91 Pds_add_numval(pds, msg->payload.pingStats.resync);
92 Pds_add_double(pds, msg->payload.pingStats.dUDPPingAvg);
93 Pds_add_double(pds, msg->payload.pingStats.dUDPPingVar);
94 Pds_add_numval(pds, msg->payload.pingStats.UDPPackets);
95 Pds_add_double(pds, msg->payload.pingStats.dTCPPingAvg);
96 Pds_add_double(pds, msg->payload.pingStats.dTCPPingVar);
97 Pds_add_numval(pds, msg->payload.pingStats.TCPPackets);
103 case PlayerSelfMuteDeaf:
106 Pds_add_numval(pds, msg->payload.textMessage.victim);
107 Pds_add_numval(pds, msg->payload.textMessage.channel);
108 Pds_add_numval(pds, msg->payload.textMessage.bTree);
109 Pds_add_string(pds, msg->payload.textMessage.message);
111 case PermissionDenied:
112 Pds_add_string(pds, msg->payload.permissionDenied.reason);
115 Pds_append_data(pds, msg->payload.cryptSetup.key, AES_BLOCK_SIZE);
116 Pds_append_data(pds, msg->payload.cryptSetup.serverNonce, AES_BLOCK_SIZE);
117 Pds_append_data(pds, msg->payload.cryptSetup.clientNonce, AES_BLOCK_SIZE);
120 if (!msg->payload.cryptSync.empty)
121 Pds_append_data(pds, msg->payload.cryptSync.nonce, AES_BLOCK_SIZE);
128 Log_warn("Unsupported message %d", msg->messageType);
136 message_t *Msg_create(messageType_t messageType)
138 message_t *msg = malloc(sizeof(message_t));
141 Log_fatal("Out of memory");
142 memset(msg, 0, sizeof(message_t));
144 msg->messageType = messageType;
145 init_list_entry(&msg->node);
147 if (msg->messageType == Speex) {
148 msg->payload.speex.data = malloc(SPEEX_DATA_SIZE);
149 if (msg->payload.speex.data == NULL)
150 Log_fatal("Out of memory");
155 void Msg_inc_ref(message_t *msg)
160 void Msg_free(message_t *msg)
162 if (msg->refcount) msg->refcount--;
163 if (msg->refcount > 0)
165 if (msg->messageType == Speex)
166 free(msg->payload.speex.data);
170 void dumpmsg(uint8_t *data, int size)
172 int i, r = 0, offset = 0;
175 while (r * 8 + i < size) {
176 for (i = 0; i < 8 && r * 8 + i < size; i++) {
177 offset += sprintf(buf + offset, "%x ", data[r * 8 + i]);
179 sprintf(buf + offset, "\n");
187 message_t *Msg_networkToMessage(uint8_t *data, int size)
189 message_t *msg = NULL;
194 pds = Pds_create(data, size);
195 messageType = Pds_get_numval(pds);
196 sessionId = Pds_get_numval(pds);
198 switch (messageType) {
200 msg = Msg_create(Speex);
201 msg->payload.speex.seq = Pds_get_numval(pds);
202 msg->payload.speex.size = pds->maxsize - pds->offset;
203 memcpy(msg->payload.speex.data, &pds->data[pds->offset], pds->maxsize - pds->offset);
205 case ServerAuthenticate:
206 msg = Msg_create(ServerAuthenticate);
207 msg->payload.serverAuthenticate.version = Pds_get_numval(pds);
208 Pds_get_string(pds, msg->payload.serverAuthenticate.userName, MAX_TEXT);
209 Pds_get_string(pds, msg->payload.serverAuthenticate.password, MAX_TEXT);
212 msg = Msg_create(ServerReject);
215 msg = Msg_create(ServerSync);
218 msg = Msg_create(ServerJoin);
221 msg = Msg_create(ServerLeave);
224 msg = Msg_create(QueryUsers);
227 msg = Msg_create(Ping);
228 msg->payload.ping.timestamp = Pds_get_numval(pds);
231 msg = Msg_create(PingStats);
232 msg->payload.pingStats.timestamp = Pds_get_numval(pds);
233 msg->payload.pingStats.good = Pds_get_numval(pds);
234 msg->payload.pingStats.late = Pds_get_numval(pds);
235 msg->payload.pingStats.lost = Pds_get_numval(pds);
236 msg->payload.pingStats.resync = Pds_get_numval(pds);
237 msg->payload.pingStats.dUDPPingAvg = Pds_get_double(pds);
238 msg->payload.pingStats.dUDPPingVar = Pds_get_double(pds);
239 msg->payload.pingStats.UDPPackets = Pds_get_numval(pds);
240 msg->payload.pingStats.dTCPPingAvg = Pds_get_double(pds);
241 msg->payload.pingStats.dTCPPingVar = Pds_get_double(pds);
242 msg->payload.pingStats.TCPPackets = Pds_get_numval(pds);
245 msg = Msg_create(PlayerMute);
246 msg->payload.playerMute.victim = Pds_get_numval(pds);
247 msg->payload.playerMute.bMute = Pds_get_numval(pds);
250 msg = Msg_create(PlayerDeaf);
251 msg->payload.playerDeaf.victim = Pds_get_numval(pds);
252 msg->payload.playerDeaf.bDeaf = Pds_get_numval(pds);
254 case PlayerSelfMuteDeaf:
255 msg = Msg_create(PlayerSelfMuteDeaf);
256 msg->payload.playerSelfMuteDeaf.bMute = Pds_get_numval(pds);
257 msg->payload.playerSelfMuteDeaf.bDeaf = Pds_get_numval(pds);
260 msg = Msg_create(TextMessage);
261 msg->payload.textMessage.victim = Pds_get_numval(pds);
262 msg->payload.textMessage.channel = Pds_get_numval(pds);
263 msg->payload.textMessage.bTree = Pds_get_numval(pds);
264 Pds_get_string(pds, msg->payload.textMessage.message, MAX_TEXT);
266 case PermissionDenied:
267 Log_warn("Ignoring message PermissionDenied - not supported");
270 Log_warn("Ignoring message CryptSetup - not supported");
273 msg = Msg_create(CryptSync);
274 if (Pds_get_data(pds, msg->payload.cryptSync.nonce, AES_BLOCK_SIZE) == 0)
275 msg->payload.cryptSync.empty = true;
277 msg->payload.cryptSync.empty = false;
280 msg = Msg_create(PlayerMove);
281 msg->payload.playerMove.victim = Pds_get_numval(pds);
282 msg->payload.playerMove.channel = Pds_get_numval(pds);
285 /* The commands below are not supported -> no need to read the parameters */
287 msg = Msg_create(PlayerRename);
290 msg = Msg_create(ChannelAdd);
292 case ChannelDescUpdate:
293 msg = Msg_create(ChannelDescUpdate);
296 msg = Msg_create(ContextAction);
298 case ContextAddAction:
299 msg = Msg_create(ContextAddAction);
302 msg = Msg_create(ServerBanList);
305 msg = Msg_create(PlayerKick);
308 msg = Msg_create(PlayerBan);
311 msg = Msg_create(ChannelRemove);
314 msg = Msg_create(ChannelMove);
317 msg = Msg_create(ChannelLink);
320 msg = Msg_create(ChannelRename);
323 msg = Msg_create(EditACL);
326 msg = Msg_create(PlayerTexture);
329 Log_warn("Message: Type %d (session %d) is unknown type", messageType, sessionId);
332 msg->sessionId = sessionId;
337 Log_warn("Message: Type %d (session %d, size %d) corrupt or short packet",
338 messageType, sessionId, pds->offset);
339 } else if (pds->maxsize - pds->offset != 0) {
342 Log_warn("Message: Type %d (session %d) Long packet: %d/%d leftover bytes",
343 messageType, sessionId, pds->overshoot, pds->offset);
344 } else if (!pds->bOk) {
347 Log_warn("Message: Type %d (session %d, size %d) failed to validate", messageType, sessionId, pds->maxsize);