1 /* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2010, 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.
35 #include <arpa/inet.h>
42 #define PREAMBLE_SIZE 6
44 static message_t *Msg_create_nopayload(messageType_t messageType);
46 static void Msg_addPreamble(uint8_t *buffer, uint16_t type, uint32_t len)
48 buffer[1] = (type) & 0xff;
49 buffer[0] = (type >> 8) & 0xff;
51 buffer[5] = (len) & 0xff;
52 buffer[4] = (len >> 8) & 0xff;
53 buffer[3] = (len >> 16) & 0xff;
54 buffer[2] = (len >> 24) & 0xff;
57 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
62 msgType = buffer[1] | (buffer[0] << 8);
63 msgLen = buffer[5] | (buffer[4] << 8) | (buffer[3] << 16) | (buffer[2] << 24);
68 #define MAX_MSGSIZE (BUFSIZE - PREAMBLE_SIZE)
69 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
72 uint8_t *bufptr = buffer + PREAMBLE_SIZE;
74 Log_debug("To net: msg type %d", msg->messageType);
75 switch (msg->messageType) {
77 len = mumble_proto__version__get_packed_size(msg->payload.version);
78 if (len > MAX_MSGSIZE) {
79 Log_warn("Too big tx message. Discarding");
82 Msg_addPreamble(buffer, msg->messageType, len);
83 mumble_proto__version__pack(msg->payload.version, bufptr);
85 case UDPTunnel: /* Non-standard handling of tunneled voice traffic. */
86 if (msg->payload.UDPTunnel->packet.len > MAX_MSGSIZE) {
87 Log_warn("Too big tx message. Discarding");
90 len = msg->payload.UDPTunnel->packet.len;
91 Msg_addPreamble(buffer, msg->messageType, msg->payload.UDPTunnel->packet.len);
92 memcpy(bufptr, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
95 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
96 if (len > MAX_MSGSIZE) {
97 Log_warn("Too big tx message. Discarding");
100 Msg_addPreamble(buffer, msg->messageType, len);
101 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
104 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
105 if (len > MAX_MSGSIZE) {
106 Log_warn("Too big tx message. Discarding");
109 Msg_addPreamble(buffer, msg->messageType, len);
110 mumble_proto__ping__pack(msg->payload.ping, bufptr);
113 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
114 if (len > MAX_MSGSIZE) {
115 Log_warn("Too big tx message. Discarding");
118 Msg_addPreamble(buffer, msg->messageType, len);
119 mumble_proto__reject__pack(msg->payload.reject, bufptr);
122 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
123 if (len > MAX_MSGSIZE) {
124 Log_warn("Too big tx message. Discarding");
127 Msg_addPreamble(buffer, msg->messageType, len);
128 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
131 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
132 if (len > MAX_MSGSIZE) {
133 Log_warn("Too big tx message. Discarding");
136 Msg_addPreamble(buffer, msg->messageType, len);
137 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
139 case PermissionDenied:
140 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
141 if (len > MAX_MSGSIZE) {
142 Log_warn("Too big tx message. Discarding");
145 Msg_addPreamble(buffer, msg->messageType, len);
146 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
149 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
150 if (len > MAX_MSGSIZE) {
151 Log_warn("Too big tx message. Discarding");
154 Msg_addPreamble(buffer, msg->messageType, len);
155 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
158 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
159 if (len > MAX_MSGSIZE) {
160 Log_warn("Too big tx message. Discarding");
163 Msg_addPreamble(buffer, msg->messageType, len);
164 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
167 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
168 if (len > MAX_MSGSIZE) {
169 Log_warn("Too big tx message. Discarding");
172 Msg_addPreamble(buffer, msg->messageType, len);
173 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
176 len = mumble_proto__user_remove__get_packed_size(msg->payload.userRemove);
177 if (len > MAX_MSGSIZE) {
178 Log_warn("Too big tx message. Discarding");
181 Msg_addPreamble(buffer, msg->messageType, len);
182 mumble_proto__user_remove__pack(msg->payload.userRemove, bufptr);
185 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
186 if (len > MAX_MSGSIZE) {
187 Log_warn("Too big tx message. Discarding");
190 Msg_addPreamble(buffer, msg->messageType, len);
191 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
194 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
195 if (len > MAX_MSGSIZE) {
196 Log_warn("Too big tx message. Discarding");
199 Msg_addPreamble(buffer, msg->messageType, len);
200 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
203 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
204 if (len > MAX_MSGSIZE) {
205 Log_warn("Too big tx message. Discarding");
208 Msg_addPreamble(buffer, msg->messageType, len);
209 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
211 case PermissionQuery:
212 len = mumble_proto__permission_query__get_packed_size(msg->payload.permissionQuery);
213 if (len > MAX_MSGSIZE) {
214 Log_warn("Too big tx message. Discarding");
217 Msg_addPreamble(buffer, msg->messageType, len);
218 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
221 len = mumble_proto__channel_remove__get_packed_size(msg->payload.channelRemove);
222 if (len > MAX_MSGSIZE) {
223 Log_warn("Too big tx message. Discarding");
226 Msg_addPreamble(buffer, msg->messageType, len);
227 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
231 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
234 return len + PREAMBLE_SIZE;
237 static message_t *Msg_create_nopayload(messageType_t messageType)
239 message_t *msg = malloc(sizeof(message_t));
242 Log_fatal("Out of memory");
243 memset(msg, 0, sizeof(message_t));
245 msg->messageType = messageType;
246 init_list_entry(&msg->node);
250 message_t *Msg_create(messageType_t messageType)
252 message_t *msg = Msg_create_nopayload(messageType);
254 switch (messageType) {
256 msg->payload.version = malloc(sizeof(MumbleProto__Version));
257 mumble_proto__version__init(msg->payload.version);
260 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
261 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
264 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
265 mumble_proto__authenticate__init(msg->payload.authenticate);
268 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
269 mumble_proto__ping__init(msg->payload.ping);
272 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
273 mumble_proto__reject__init(msg->payload.reject);
276 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
277 mumble_proto__server_sync__init(msg->payload.serverSync);
280 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
281 mumble_proto__text_message__init(msg->payload.textMessage);
283 case PermissionDenied:
284 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
285 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
288 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
289 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
292 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
293 mumble_proto__user_list__init(msg->payload.userList);
296 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
297 mumble_proto__user_state__init(msg->payload.userState);
300 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
301 mumble_proto__channel_state__init(msg->payload.channelState);
304 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
305 mumble_proto__user_remove__init(msg->payload.userRemove);
308 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
309 mumble_proto__voice_target__init(msg->payload.voiceTarget);
312 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
313 mumble_proto__codec_version__init(msg->payload.codecVersion);
315 case PermissionQuery:
316 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
317 mumble_proto__permission_query__init(msg->payload.permissionQuery);
320 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
321 mumble_proto__channel_remove__init(msg->payload.channelRemove);
325 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
332 void Msg_inc_ref(message_t *msg)
337 void Msg_free(message_t *msg)
339 if (msg->refcount) msg->refcount--;
340 if (msg->refcount > 0)
343 switch (msg->messageType) {
346 mumble_proto__version__free_unpacked(msg->payload.version, NULL);
348 if (msg->payload.version->release)
349 free(msg->payload.version->release);
350 if (msg->payload.version->os)
351 free(msg->payload.version->os);
352 if (msg->payload.version->os_version)
353 free(msg->payload.version->os_version);
354 free(msg->payload.version);
359 mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
361 free(msg->payload.UDPTunnel->packet.data);
362 free(msg->payload.UDPTunnel);
367 mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
369 free(msg->payload.authenticate);
373 mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
375 free(msg->payload.ping);
380 mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
382 free(msg->payload.reject->reason);
383 free(msg->payload.reject);
388 mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
390 free(msg->payload.serverSync->welcome_text);
391 free(msg->payload.serverSync);
396 mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
398 free(msg->payload.textMessage);
401 case PermissionDenied:
403 mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
405 free(msg->payload.permissionDenied->reason);
406 free(msg->payload.permissionDenied);
411 mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
413 free(msg->payload.cryptSetup);
418 mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
420 free(msg->payload.userList);
425 mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
427 free(msg->payload.userState->name);
428 free(msg->payload.userState);
433 mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
435 if (msg->payload.channelState->name)
436 free(msg->payload.channelState->name);
437 if (msg->payload.channelState->description)
438 free(msg->payload.channelState->description);
439 if (msg->payload.channelState->links)
440 free(msg->payload.channelState->links);
441 free(msg->payload.channelState);
446 mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
448 free(msg->payload.userRemove);
453 mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
455 free(msg->payload.voiceTarget);
460 mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
462 free(msg->payload.codecVersion);
465 case PermissionQuery:
467 mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
469 free(msg->payload.permissionQuery);
474 mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
476 free(msg->payload.channelRemove);
481 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
487 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
489 message_t *msg = NULL;
491 msg = Msg_create_nopayload(UDPTunnel);
492 msg->unpacked = false;
493 msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
494 if (msg->payload.UDPTunnel == NULL)
495 Log_fatal("Out of memory");
496 msg->payload.UDPTunnel->packet.data = malloc(size);
497 if (msg->payload.UDPTunnel->packet.data == NULL)
498 Log_fatal("Out of memory");
499 memcpy(msg->payload.UDPTunnel->packet.data, data, size);
500 msg->payload.UDPTunnel->packet.len = size;
504 message_t *Msg_networkToMessage(uint8_t *data, int size)
506 message_t *msg = NULL;
507 uint8_t *msgData = &data[6];
508 int messageType, msgLen;
510 Msg_getPreamble(data, &messageType, &msgLen);
512 Log_debug("Message type %d size %d", messageType, msgLen);
513 //dumpmsg(data, size);
515 switch (messageType) {
518 msg = Msg_create_nopayload(Version);
519 msg->unpacked = true;
520 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
521 if (msg->payload.version == NULL)
525 case UDPTunnel: /* Non-standard handling of tunneled voice data */
527 msg = Msg_CreateVoiceMsg(msgData, msgLen);
532 msg = Msg_create_nopayload(Authenticate);
533 msg->unpacked = true;
534 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
535 if (msg->payload.authenticate == NULL)
541 msg = Msg_create_nopayload(Ping);
542 msg->unpacked = true;
543 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
544 if (msg->payload.ping == NULL)
550 msg = Msg_create_nopayload(Reject);
551 msg->unpacked = true;
552 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
553 if (msg->payload.reject == NULL)
559 msg = Msg_create_nopayload(ServerSync);
560 msg->unpacked = true;
561 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
562 if (msg->payload.serverSync == NULL)
568 msg = Msg_create_nopayload(TextMessage);
569 msg->unpacked = true;
570 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
571 if (msg->payload.textMessage == NULL)
575 case PermissionDenied:
577 msg = Msg_create_nopayload(PermissionDenied);
578 msg->unpacked = true;
579 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
580 if (msg->payload.permissionDenied == NULL)
586 msg = Msg_create_nopayload(CryptSetup);
587 msg->unpacked = true;
588 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
589 if (msg->payload.cryptSetup == NULL)
595 msg = Msg_create_nopayload(UserList);
596 msg->unpacked = true;
597 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
598 if (msg->payload.userList == NULL)
604 msg = Msg_create_nopayload(UserState);
605 msg->unpacked = true;
606 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
607 if (msg->payload.userState == NULL)
613 msg = Msg_create_nopayload(ChannelState);
614 msg->unpacked = true;
615 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
616 if (msg->payload.channelState == NULL)
622 msg = Msg_create_nopayload(VoiceTarget);
623 msg->unpacked = true;
624 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
625 if (msg->payload.voiceTarget == NULL)
631 msg = Msg_create_nopayload(CodecVersion);
632 msg->unpacked = true;
633 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
634 if (msg->payload.codecVersion == NULL)
638 case PermissionQuery:
640 msg = Msg_create_nopayload(PermissionQuery);
641 msg->unpacked = true;
642 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
643 if (msg->payload.permissionQuery == NULL)
649 msg = Msg_create_nopayload(ChannelRemove);
650 msg->unpacked = true;
651 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
652 if (msg->payload.channelRemove == NULL)
658 Log_warn("Unsupported message %d", messageType);