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)
51 buffer[0] = (type) & 0xff;
52 buffer[1] = (type >> 8) & 0xff;
54 buffer[2] = (len) & 0xff;
55 buffer[3] = (len >> 8) & 0xff;
56 buffer[4] = (len >> 16) & 0xff;
57 buffer[5] = (len >> 24) & 0xff;
60 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
65 msgType = buffer[0] | (buffer[1] << 8);
66 msgLen = buffer[2] | (buffer[3] << 8) | (buffer[4] << 16) | (buffer[5] << 24);
67 *type = (int)ntohs(msgType);
68 *len = (int)ntohl(msgLen);
71 #define MAX_MSGSIZE (BUFSIZE - PREAMBLE_SIZE)
72 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
75 uint8_t *bufptr = buffer + PREAMBLE_SIZE;
77 Log_debug("To net: msg type %d", msg->messageType);
78 switch (msg->messageType) {
80 len = mumble_proto__version__get_packed_size(msg->payload.version);
81 if (len > MAX_MSGSIZE) {
82 Log_warn("Too big tx message. Discarding");
85 Msg_addPreamble(buffer, msg->messageType, len);
86 mumble_proto__version__pack(msg->payload.version, bufptr);
88 case UDPTunnel: /* Non-standard handling of tunneled voice traffic. */
89 if (msg->payload.UDPTunnel->packet.len > MAX_MSGSIZE) {
90 Log_warn("Too big tx message. Discarding");
93 len = msg->payload.UDPTunnel->packet.len;
94 Msg_addPreamble(buffer, msg->messageType, msg->payload.UDPTunnel->packet.len);
95 memcpy(bufptr, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
98 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
99 if (len > MAX_MSGSIZE) {
100 Log_warn("Too big tx message. Discarding");
103 Msg_addPreamble(buffer, msg->messageType, len);
104 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
107 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
108 if (len > MAX_MSGSIZE) {
109 Log_warn("Too big tx message. Discarding");
112 Msg_addPreamble(buffer, msg->messageType, len);
113 mumble_proto__ping__pack(msg->payload.ping, bufptr);
116 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
117 if (len > MAX_MSGSIZE) {
118 Log_warn("Too big tx message. Discarding");
121 Msg_addPreamble(buffer, msg->messageType, len);
122 mumble_proto__reject__pack(msg->payload.reject, bufptr);
125 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
126 if (len > MAX_MSGSIZE) {
127 Log_warn("Too big tx message. Discarding");
130 Msg_addPreamble(buffer, msg->messageType, len);
131 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
134 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
135 if (len > MAX_MSGSIZE) {
136 Log_warn("Too big tx message. Discarding");
139 Msg_addPreamble(buffer, msg->messageType, len);
140 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
142 case PermissionDenied:
143 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
144 if (len > MAX_MSGSIZE) {
145 Log_warn("Too big tx message. Discarding");
148 Msg_addPreamble(buffer, msg->messageType, len);
149 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
152 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
153 if (len > MAX_MSGSIZE) {
154 Log_warn("Too big tx message. Discarding");
157 Msg_addPreamble(buffer, msg->messageType, len);
158 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
161 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
162 if (len > MAX_MSGSIZE) {
163 Log_warn("Too big tx message. Discarding");
166 Msg_addPreamble(buffer, msg->messageType, len);
167 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
170 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
171 if (len > MAX_MSGSIZE) {
172 Log_warn("Too big tx message. Discarding");
175 Msg_addPreamble(buffer, msg->messageType, len);
176 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
179 len = mumble_proto__user_remove__get_packed_size(msg->payload.userRemove);
180 if (len > MAX_MSGSIZE) {
181 Log_warn("Too big tx message. Discarding");
184 Msg_addPreamble(buffer, msg->messageType, len);
185 mumble_proto__user_remove__pack(msg->payload.userRemove, bufptr);
188 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
189 if (len > MAX_MSGSIZE) {
190 Log_warn("Too big tx message. Discarding");
193 Msg_addPreamble(buffer, msg->messageType, len);
194 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
197 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
198 if (len > MAX_MSGSIZE) {
199 Log_warn("Too big tx message. Discarding");
202 Msg_addPreamble(buffer, msg->messageType, len);
203 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
206 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
207 if (len > MAX_MSGSIZE) {
208 Log_warn("Too big tx message. Discarding");
211 Msg_addPreamble(buffer, msg->messageType, len);
212 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
214 case PermissionQuery:
215 len = mumble_proto__permission_query__get_packed_size(msg->payload.permissionQuery);
216 if (len > MAX_MSGSIZE) {
217 Log_warn("Too big tx message. Discarding");
220 Msg_addPreamble(buffer, msg->messageType, len);
221 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
224 len = mumble_proto__channel_remove__get_packed_size(msg->payload.channelRemove);
225 if (len > MAX_MSGSIZE) {
226 Log_warn("Too big tx message. Discarding");
229 Msg_addPreamble(buffer, msg->messageType, len);
230 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
234 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
237 return len + PREAMBLE_SIZE;
240 static message_t *Msg_create_nopayload(messageType_t messageType)
242 message_t *msg = malloc(sizeof(message_t));
245 Log_fatal("Out of memory");
246 memset(msg, 0, sizeof(message_t));
248 msg->messageType = messageType;
249 init_list_entry(&msg->node);
253 message_t *Msg_create(messageType_t messageType)
255 message_t *msg = Msg_create_nopayload(messageType);
257 switch (messageType) {
259 msg->payload.version = malloc(sizeof(MumbleProto__Version));
260 mumble_proto__version__init(msg->payload.version);
263 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
264 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
267 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
268 mumble_proto__authenticate__init(msg->payload.authenticate);
271 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
272 mumble_proto__ping__init(msg->payload.ping);
275 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
276 mumble_proto__reject__init(msg->payload.reject);
279 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
280 mumble_proto__server_sync__init(msg->payload.serverSync);
283 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
284 mumble_proto__text_message__init(msg->payload.textMessage);
286 case PermissionDenied:
287 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
288 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
291 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
292 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
295 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
296 mumble_proto__user_list__init(msg->payload.userList);
299 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
300 mumble_proto__user_state__init(msg->payload.userState);
303 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
304 mumble_proto__channel_state__init(msg->payload.channelState);
307 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
308 mumble_proto__user_remove__init(msg->payload.userRemove);
311 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
312 mumble_proto__voice_target__init(msg->payload.voiceTarget);
315 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
316 mumble_proto__codec_version__init(msg->payload.codecVersion);
318 case PermissionQuery:
319 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
320 mumble_proto__permission_query__init(msg->payload.permissionQuery);
323 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
324 mumble_proto__channel_remove__init(msg->payload.channelRemove);
328 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
335 void Msg_inc_ref(message_t *msg)
340 void Msg_free(message_t *msg)
342 if (msg->refcount) msg->refcount--;
343 if (msg->refcount > 0)
346 switch (msg->messageType) {
349 mumble_proto__version__free_unpacked(msg->payload.version, NULL);
351 if (msg->payload.version->release)
352 free(msg->payload.version->release);
353 if (msg->payload.version->os)
354 free(msg->payload.version->os);
355 if (msg->payload.version->os_version)
356 free(msg->payload.version->os_version);
357 free(msg->payload.version);
362 mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
364 free(msg->payload.UDPTunnel->packet.data);
365 free(msg->payload.UDPTunnel);
370 mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
372 free(msg->payload.authenticate);
376 mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
378 free(msg->payload.ping);
383 mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
385 free(msg->payload.reject->reason);
386 free(msg->payload.reject);
391 mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
393 free(msg->payload.serverSync->welcome_text);
394 free(msg->payload.serverSync);
399 mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
401 free(msg->payload.textMessage);
404 case PermissionDenied:
406 mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
408 free(msg->payload.permissionDenied->reason);
409 free(msg->payload.permissionDenied);
414 mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
416 free(msg->payload.cryptSetup);
421 mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
423 free(msg->payload.userList);
428 mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
430 free(msg->payload.userState->name);
431 free(msg->payload.userState);
436 mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
438 if (msg->payload.channelState->name)
439 free(msg->payload.channelState->name);
440 if (msg->payload.channelState->description)
441 free(msg->payload.channelState->description);
442 if (msg->payload.channelState->links)
443 free(msg->payload.channelState->links);
444 free(msg->payload.channelState);
449 mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
451 free(msg->payload.userRemove);
456 mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
458 free(msg->payload.voiceTarget);
463 mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
465 free(msg->payload.codecVersion);
468 case PermissionQuery:
470 mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
472 free(msg->payload.permissionQuery);
477 mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
479 free(msg->payload.channelRemove);
484 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
490 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
492 message_t *msg = NULL;
494 msg = Msg_create_nopayload(UDPTunnel);
495 msg->unpacked = false;
496 msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
497 if (msg->payload.UDPTunnel == NULL)
498 Log_fatal("Out of memory");
499 msg->payload.UDPTunnel->packet.data = malloc(size);
500 if (msg->payload.UDPTunnel->packet.data == NULL)
501 Log_fatal("Out of memory");
502 memcpy(msg->payload.UDPTunnel->packet.data, data, size);
503 msg->payload.UDPTunnel->packet.len = size;
507 message_t *Msg_networkToMessage(uint8_t *data, int size)
509 message_t *msg = NULL;
510 uint8_t *msgData = &data[6];
511 int messageType, msgLen;
513 Msg_getPreamble(data, &messageType, &msgLen);
515 Log_debug("Message type %d size %d", messageType, msgLen);
516 //dumpmsg(data, size);
518 switch (messageType) {
521 msg = Msg_create_nopayload(Version);
522 msg->unpacked = true;
523 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
524 if (msg->payload.version == NULL)
528 case UDPTunnel: /* Non-standard handling of tunneled voice data */
530 msg = Msg_CreateVoiceMsg(msgData, msgLen);
535 msg = Msg_create_nopayload(Authenticate);
536 msg->unpacked = true;
537 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
538 if (msg->payload.authenticate == NULL)
544 msg = Msg_create_nopayload(Ping);
545 msg->unpacked = true;
546 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
547 if (msg->payload.ping == NULL)
553 msg = Msg_create_nopayload(Reject);
554 msg->unpacked = true;
555 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
556 if (msg->payload.reject == NULL)
562 msg = Msg_create_nopayload(ServerSync);
563 msg->unpacked = true;
564 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
565 if (msg->payload.serverSync == NULL)
571 msg = Msg_create_nopayload(TextMessage);
572 msg->unpacked = true;
573 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
574 if (msg->payload.textMessage == NULL)
578 case PermissionDenied:
580 msg = Msg_create_nopayload(PermissionDenied);
581 msg->unpacked = true;
582 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
583 if (msg->payload.permissionDenied == NULL)
589 msg = Msg_create_nopayload(CryptSetup);
590 msg->unpacked = true;
591 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
592 if (msg->payload.cryptSetup == NULL)
598 msg = Msg_create_nopayload(UserList);
599 msg->unpacked = true;
600 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
601 if (msg->payload.userList == NULL)
607 msg = Msg_create_nopayload(UserState);
608 msg->unpacked = true;
609 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
610 if (msg->payload.userState == NULL)
616 msg = Msg_create_nopayload(ChannelState);
617 msg->unpacked = true;
618 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
619 if (msg->payload.channelState == NULL)
625 msg = Msg_create_nopayload(VoiceTarget);
626 msg->unpacked = true;
627 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
628 if (msg->payload.voiceTarget == NULL)
634 msg = Msg_create_nopayload(CodecVersion);
635 msg->unpacked = true;
636 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
637 if (msg->payload.codecVersion == NULL)
641 case PermissionQuery:
643 msg = Msg_create_nopayload(PermissionQuery);
644 msg->unpacked = true;
645 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
646 if (msg->payload.permissionQuery == NULL)
652 msg = Msg_create_nopayload(ChannelRemove);
653 msg->unpacked = true;
654 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
655 if (msg->payload.channelRemove == NULL)
661 Log_warn("Unsupported message %d", messageType);