Fix for:
[umurmur.git] / src / messages.c
1 /* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
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.
18
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.
30 */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <arpa/inet.h>
36
37 #include "messages.h"
38 #include "client.h"
39 #include "pds.h"
40 #include "log.h"
41
42 #define PREAMBLE_SIZE 6
43
44 static void dumpmsg(uint8_t *data, int size);
45 static message_t *Msg_create_nopayload(messageType_t messageType);
46
47 static void Msg_addPreamble(uint8_t *buffer, uint16_t type, uint32_t len)
48 {
49         type = htons(type);
50         len = htonl(len);
51         
52         buffer[0] = (type) & 0xff;
53         buffer[1] = (type >> 8) & 0xff;
54         
55         buffer[2] = (len) & 0xff;
56         buffer[3] = (len >> 8) & 0xff;
57         buffer[4] = (len >> 16) & 0xff;
58         buffer[5] = (len >> 24) & 0xff; 
59 }
60
61 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
62 {
63         uint16_t msgType;
64         uint32_t msgLen;
65         
66         msgType = buffer[0] | (buffer[1] << 8);
67         msgLen = buffer[2] | (buffer[3] << 8) | (buffer[4] << 16) | (buffer[5] << 24);
68         *type = (int)ntohs(msgType);
69         *len = (int)ntohl(msgLen);
70 }
71
72 #define MAX_MSGSIZE (BUFSIZE - PREAMBLE_SIZE)
73 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
74 {
75         int len;
76         uint8_t *bufptr = buffer + PREAMBLE_SIZE;
77                 
78         Log_debug("To net: msg type %d", msg->messageType);
79         switch (msg->messageType) {
80         case Version:
81                 len = mumble_proto__version__get_packed_size(msg->payload.version);
82                 if (len > MAX_MSGSIZE) {
83                         Log_warn("Too big tx message. Discarding");
84                         break;
85                 }
86                 Msg_addPreamble(buffer, msg->messageType, len);
87                 mumble_proto__version__pack(msg->payload.version, bufptr);
88                 break;
89         case UDPTunnel: /* Non-standard handling of tunneled voice traffic. */
90                 if (msg->payload.UDPTunnel->packet.len > MAX_MSGSIZE) {
91                         Log_warn("Too big tx message. Discarding");
92                         break;
93                 }
94                 len = msg->payload.UDPTunnel->packet.len;
95                 Msg_addPreamble(buffer, msg->messageType, msg->payload.UDPTunnel->packet.len);
96                 memcpy(bufptr, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
97                 break;
98         case Authenticate:
99                 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
100                 if (len > MAX_MSGSIZE) {
101                         Log_warn("Too big tx message. Discarding");
102                         break;
103                         }
104                 Msg_addPreamble(buffer, msg->messageType, len);
105                 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
106                 break;
107         case Ping:
108                 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
109                 if (len > MAX_MSGSIZE) {
110                         Log_warn("Too big tx message. Discarding");
111                         break;
112                         }
113                 Msg_addPreamble(buffer, msg->messageType, len);
114                 mumble_proto__ping__pack(msg->payload.ping, bufptr);
115                 break;
116         case Reject:
117                 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
118                 if (len > MAX_MSGSIZE) {
119                         Log_warn("Too big tx message. Discarding");
120                         break;
121                         }
122                 Msg_addPreamble(buffer, msg->messageType, len);
123                 mumble_proto__reject__pack(msg->payload.reject, bufptr);
124                 break;
125         case ServerSync:
126                 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
127                 if (len > MAX_MSGSIZE) {
128                         Log_warn("Too big tx message. Discarding");
129                         break;
130                         }
131                 Msg_addPreamble(buffer, msg->messageType, len);
132                 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
133                 break;
134         case TextMessage:
135                 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
136                 if (len > MAX_MSGSIZE) {
137                         Log_warn("Too big tx message. Discarding");
138                         break;
139                         }
140                 Msg_addPreamble(buffer, msg->messageType, len);
141                 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
142                 break;
143         case PermissionDenied:
144                 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
145                 if (len > MAX_MSGSIZE) {
146                         Log_warn("Too big tx message. Discarding");
147                         break;
148                         }
149                 Msg_addPreamble(buffer, msg->messageType, len);
150                 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
151                 break;
152         case CryptSetup:
153                 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
154                 if (len > MAX_MSGSIZE) {
155                         Log_warn("Too big tx message. Discarding");
156                         break;
157                         }
158                 Msg_addPreamble(buffer, msg->messageType, len);
159                 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
160                 break;
161         case UserList:
162                 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
163                 if (len > MAX_MSGSIZE) {
164                         Log_warn("Too big tx message. Discarding");
165                         break;
166                         }
167                 Msg_addPreamble(buffer, msg->messageType, len);
168                 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
169                 break;
170         case UserState:
171                 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
172                 if (len > MAX_MSGSIZE) {
173                         Log_warn("Too big tx message. Discarding");
174                         break;
175                         }
176                 Msg_addPreamble(buffer, msg->messageType, len);
177                 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
178                 break;
179         case UserRemove:
180                 len = mumble_proto__user_remove__get_packed_size(msg->payload.userRemove);
181                 if (len > MAX_MSGSIZE) {
182                         Log_warn("Too big tx message. Discarding");
183                         break;
184                         }
185                 Msg_addPreamble(buffer, msg->messageType, len);
186                 mumble_proto__user_remove__pack(msg->payload.userRemove, bufptr);
187                 break;
188         case ChannelState:
189                 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
190                 if (len > MAX_MSGSIZE) {
191                         Log_warn("Too big tx message. Discarding");
192                         break;
193                         }
194                 Msg_addPreamble(buffer, msg->messageType, len);
195                 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
196                 break;
197         case VoiceTarget:
198                 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
199                 if (len > MAX_MSGSIZE) {
200                         Log_warn("Too big tx message. Discarding");
201                         break;
202                         }
203                 Msg_addPreamble(buffer, msg->messageType, len);
204                 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
205                 break;
206         case CodecVersion:
207                 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
208                 if (len > MAX_MSGSIZE) {
209                         Log_warn("Too big tx message. Discarding");
210                         break;
211                         }
212                 Msg_addPreamble(buffer, msg->messageType, len);
213                 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
214                 break;
215         case PermissionQuery:
216                 len = mumble_proto__permission_query__get_packed_size(msg->payload.permissionQuery);
217                 if (len > MAX_MSGSIZE) {
218                         Log_warn("Too big tx message. Discarding");
219                         break;
220                         }
221                 Msg_addPreamble(buffer, msg->messageType, len);
222                 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
223                 break;
224         case ChannelRemove:
225                 len = mumble_proto__channel_remove__get_packed_size(msg->payload.channelRemove);
226                 if (len > MAX_MSGSIZE) {
227                         Log_warn("Too big tx message. Discarding");
228                         break;
229                         }
230                 Msg_addPreamble(buffer, msg->messageType, len);
231                 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
232                 break;
233
234         default:
235                 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
236                 return 0;
237         }
238         return len + PREAMBLE_SIZE;
239 }
240
241 static message_t *Msg_create_nopayload(messageType_t messageType)
242 {
243         message_t *msg = malloc(sizeof(message_t));
244
245         if (msg == NULL)
246                 Log_fatal("Out of memory");
247         memset(msg, 0, sizeof(message_t));
248         msg->refcount = 1;
249         msg->messageType = messageType;
250         init_list_entry(&msg->node);
251         return msg;
252 }
253
254 message_t *Msg_create(messageType_t messageType)
255 {
256         message_t *msg = Msg_create_nopayload(messageType);
257         
258         switch (messageType) {
259         case Version:
260                 msg->payload.version = malloc(sizeof(MumbleProto__Version));
261                 mumble_proto__version__init(msg->payload.version);
262                 break;
263         case UDPTunnel:
264                 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
265                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
266                 break;
267         case Authenticate:
268                 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
269                 mumble_proto__authenticate__init(msg->payload.authenticate);
270                 break;
271         case Ping:
272                 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
273                 mumble_proto__ping__init(msg->payload.ping);
274                 break;
275         case Reject:
276                 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
277                 mumble_proto__reject__init(msg->payload.reject);
278                 break;
279         case ServerSync:
280                 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
281                 mumble_proto__server_sync__init(msg->payload.serverSync);
282                 break;
283         case TextMessage:
284                 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
285                 mumble_proto__text_message__init(msg->payload.textMessage);
286                 break;
287         case PermissionDenied:
288                 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
289                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
290                 break;
291         case CryptSetup:
292                 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
293                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
294                 break;
295         case UserList:
296                 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
297                 mumble_proto__user_list__init(msg->payload.userList);
298                 break;
299         case UserState:
300                 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
301                 mumble_proto__user_state__init(msg->payload.userState);
302                 break;
303         case ChannelState:
304                 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
305                 mumble_proto__channel_state__init(msg->payload.channelState);
306                 break;
307         case UserRemove:
308                 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
309                 mumble_proto__user_remove__init(msg->payload.userRemove);
310                 break;
311         case VoiceTarget:
312                 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
313                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
314                 break;
315         case CodecVersion:
316                 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
317                 mumble_proto__codec_version__init(msg->payload.codecVersion);
318                 break;
319         case PermissionQuery:
320                 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
321                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
322                 break;
323         case ChannelRemove:
324                 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
325                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
326                 break;
327
328         default:
329                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
330                 break;
331         }
332
333         return msg;
334 }
335
336 void Msg_inc_ref(message_t *msg)
337 {
338         msg->refcount++;
339 }
340
341 void Msg_free(message_t *msg)
342 {
343         if (msg->refcount) msg->refcount--;
344         if (msg->refcount > 0)
345                 return;
346
347         switch (msg->messageType) {
348         case Version:
349                 if (msg->unpacked)
350                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
351                 else {
352                         if (msg->payload.version->release)
353                                 free(msg->payload.version->release);
354                         if (msg->payload.version->os)
355                                 free(msg->payload.version->os);
356                         if (msg->payload.version->os_version)
357                                 free(msg->payload.version->os_version);
358                         free(msg->payload.version);
359                 }
360                 break;
361         case UDPTunnel:
362                 if (msg->unpacked)
363                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
364                 else {
365                         free(msg->payload.UDPTunnel->packet.data);
366                         free(msg->payload.UDPTunnel);
367                 }
368                 break;
369         case Authenticate:
370                 if (msg->unpacked)
371                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
372                 else
373                         free(msg->payload.authenticate);
374                 break;
375         case Ping:
376                 if (msg->unpacked)
377                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
378                 else {
379                         free(msg->payload.ping);
380                 }
381                 break;
382         case Reject:
383                 if (msg->unpacked)
384                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
385                 else {
386                         free(msg->payload.reject->reason);
387                         free(msg->payload.reject);
388                 }
389                 break;
390         case ServerSync:
391                 if (msg->unpacked)
392                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
393                 else {
394                         free(msg->payload.serverSync->welcome_text);
395                         free(msg->payload.serverSync);
396                 }
397                 break;
398         case TextMessage:
399                 if (msg->unpacked)
400                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
401                 else {
402                         free(msg->payload.textMessage);
403                 }
404                 break;
405         case PermissionDenied:
406                 if (msg->unpacked)
407                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
408                 else {
409                         free(msg->payload.permissionDenied->reason);
410                         free(msg->payload.permissionDenied);
411                 }
412                 break;
413         case CryptSetup:
414                 if (msg->unpacked)
415                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
416                 else {
417                         free(msg->payload.cryptSetup);
418                 }
419                 break;
420         case UserList:
421                 if (msg->unpacked)
422                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
423                 else {
424                         free(msg->payload.userList);
425                 }
426                 break;
427         case UserState:
428                 if (msg->unpacked)
429                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
430                 else {
431                         free(msg->payload.userState->name);
432                         free(msg->payload.userState);
433                 }
434                 break;
435         case ChannelState:
436                 if (msg->unpacked)
437                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
438                 else {
439                         free(msg->payload.channelState->name);
440                         free(msg->payload.channelState->description);
441                         free(msg->payload.channelState);
442                 }
443                 break;
444         case UserRemove:
445                 if (msg->unpacked)
446                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
447                 else {
448                         free(msg->payload.userRemove);
449                 }
450                 break;
451         case VoiceTarget:
452                 if (msg->unpacked)
453                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
454                 else {
455                         free(msg->payload.voiceTarget);
456                 }
457                 break;
458         case CodecVersion:
459                 if (msg->unpacked)
460                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
461                 else {
462                         free(msg->payload.codecVersion);
463                 }
464                 break;
465         case PermissionQuery:
466                 if (msg->unpacked)
467                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
468                 else {
469                         free(msg->payload.permissionQuery);
470                 }
471                 break;
472         case ChannelRemove:
473                 if (msg->unpacked)
474                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
475                 else {
476                         free(msg->payload.channelRemove);
477                 }
478                 break;
479
480         default:
481                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
482                 break;
483         }
484         free(msg);
485 }
486
487 void dumpmsg(uint8_t *data, int size)
488 {
489         int i, r = 0, offset = 0;
490         char buf[512];
491         
492         while (r * 8 + i < size) {
493                 for (i = 0; i < 8 && r * 8 + i < size; i++) {
494                         offset += sprintf(buf + offset, "%x ", data[r * 8 + i]);
495                 }
496                 sprintf(buf + offset, "\n");
497                 printf(buf);
498                 offset = 0;
499                 r++;
500                 i = 0;
501         } 
502 }
503
504 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
505 {
506         message_t *msg = NULL;
507         
508         msg = Msg_create_nopayload(UDPTunnel);
509         msg->unpacked = false;
510         msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
511         if (msg->payload.UDPTunnel == NULL)
512                 Log_fatal("Out of memory");
513         msg->payload.UDPTunnel->packet.data = malloc(size);
514         if (msg->payload.UDPTunnel->packet.data == NULL)
515                 Log_fatal("Out of memory");
516         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
517         msg->payload.UDPTunnel->packet.len = size;
518         return msg;
519 }
520
521 message_t *Msg_networkToMessage(uint8_t *data, int size)
522 {
523         message_t *msg = NULL;
524         uint8_t *msgData = &data[6];
525         int messageType, msgLen;
526
527         Msg_getPreamble(data, &messageType, &msgLen);
528
529         Log_debug("Message type %d size %d", messageType, msgLen);
530         //dumpmsg(data, size);
531         
532         switch (messageType) {
533         case Version:
534         {
535                 msg = Msg_create_nopayload(Version);
536                 msg->unpacked = true;
537                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
538                 if (msg->payload.version == NULL)
539                         goto err_out;
540                 break;
541         }
542         case UDPTunnel: /* Non-standard handling of tunneled voice data */
543         {
544                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
545                 break;
546         }
547         case Authenticate:
548         {
549                 msg = Msg_create_nopayload(Authenticate);
550                 msg->unpacked = true;
551                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
552                 if (msg->payload.authenticate == NULL)
553                         goto err_out;
554                 break;
555         }
556         case Ping:
557         {
558                 msg = Msg_create_nopayload(Ping);
559                 msg->unpacked = true;
560                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
561                 if (msg->payload.ping == NULL)
562                         goto err_out;
563                 break;
564         }
565         case Reject:
566         {
567                 msg = Msg_create_nopayload(Reject);
568                 msg->unpacked = true;
569                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
570                 if (msg->payload.reject == NULL)
571                         goto err_out;
572                 break;
573         }
574         case ServerSync:
575         {
576                 msg = Msg_create_nopayload(ServerSync);
577                 msg->unpacked = true;
578                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
579                 if (msg->payload.serverSync == NULL)
580                         goto err_out;
581                 break;
582         }
583         case TextMessage:
584         {
585                 msg = Msg_create_nopayload(TextMessage);
586                 msg->unpacked = true;
587                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
588                 if (msg->payload.textMessage == NULL)
589                         goto err_out;
590                 break;
591         }
592         case PermissionDenied:
593         {
594                 msg = Msg_create_nopayload(PermissionDenied);
595                 msg->unpacked = true;
596                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
597                 if (msg->payload.permissionDenied == NULL)
598                         goto err_out;
599                 break;
600         }
601         case CryptSetup:
602         {
603                 msg = Msg_create_nopayload(CryptSetup);
604                 msg->unpacked = true;
605                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
606                 if (msg->payload.cryptSetup == NULL)
607                         goto err_out;
608                 break;
609         }
610         case UserList:
611         {
612                 msg = Msg_create_nopayload(UserList);
613                 msg->unpacked = true;
614                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
615                 if (msg->payload.userList == NULL)
616                         goto err_out;
617                 break;
618         }
619         case UserState:
620         {
621                 msg = Msg_create_nopayload(UserState);
622                 msg->unpacked = true;
623                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
624                 if (msg->payload.userState == NULL)
625                         goto err_out;
626                 break;
627         }
628         case ChannelState:
629         {
630                 msg = Msg_create_nopayload(ChannelState);
631                 msg->unpacked = true;
632                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
633                 if (msg->payload.channelState == NULL)
634                         goto err_out;
635                 break;
636         }
637         case VoiceTarget:
638         {
639                 msg = Msg_create_nopayload(VoiceTarget);
640                 msg->unpacked = true;
641                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
642                 if (msg->payload.voiceTarget == NULL)
643                         goto err_out;
644                 break;
645         }
646         case CodecVersion:
647         {
648                 msg = Msg_create_nopayload(CodecVersion);
649                 msg->unpacked = true;
650                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
651                 if (msg->payload.codecVersion == NULL)
652                         goto err_out;
653                 break;
654         }
655         case PermissionQuery:
656         {
657                 msg = Msg_create_nopayload(PermissionQuery);
658                 msg->unpacked = true;
659                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
660                 if (msg->payload.permissionQuery == NULL)
661                         goto err_out;
662                 break;
663         }
664         case ChannelRemove:
665         {
666                 msg = Msg_create_nopayload(ChannelRemove);
667                 msg->unpacked = true;
668                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
669                 if (msg->payload.channelRemove == NULL)
670                         goto err_out;
671                 break;
672         }
673
674         default:
675                 Log_warn("Unsupported message %d", messageType);
676                 break;
677         }
678         return msg;
679         
680 err_out:
681         free(msg);
682         return NULL;
683 }