Send channel links info at client connect
[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                         if (msg->payload.channelState->name)
440                                 free(msg->payload.channelState->name);
441                         if (msg->payload.channelState->description)
442                                 free(msg->payload.channelState->description);
443                         if (msg->payload.channelState->links)
444                                 free(msg->payload.channelState->links);
445                         free(msg->payload.channelState);
446                 }
447                 break;
448         case UserRemove:
449                 if (msg->unpacked)
450                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
451                 else {
452                         free(msg->payload.userRemove);
453                 }
454                 break;
455         case VoiceTarget:
456                 if (msg->unpacked)
457                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
458                 else {
459                         free(msg->payload.voiceTarget);
460                 }
461                 break;
462         case CodecVersion:
463                 if (msg->unpacked)
464                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
465                 else {
466                         free(msg->payload.codecVersion);
467                 }
468                 break;
469         case PermissionQuery:
470                 if (msg->unpacked)
471                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
472                 else {
473                         free(msg->payload.permissionQuery);
474                 }
475                 break;
476         case ChannelRemove:
477                 if (msg->unpacked)
478                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
479                 else {
480                         free(msg->payload.channelRemove);
481                 }
482                 break;
483
484         default:
485                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
486                 break;
487         }
488         free(msg);
489 }
490
491 void dumpmsg(uint8_t *data, int size)
492 {
493         int i, r = 0, offset = 0;
494         char buf[512];
495         
496         while (r * 8 + i < size) {
497                 for (i = 0; i < 8 && r * 8 + i < size; i++) {
498                         offset += sprintf(buf + offset, "%x ", data[r * 8 + i]);
499                 }
500                 sprintf(buf + offset, "\n");
501                 printf(buf);
502                 offset = 0;
503                 r++;
504                 i = 0;
505         } 
506 }
507
508 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
509 {
510         message_t *msg = NULL;
511         
512         msg = Msg_create_nopayload(UDPTunnel);
513         msg->unpacked = false;
514         msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
515         if (msg->payload.UDPTunnel == NULL)
516                 Log_fatal("Out of memory");
517         msg->payload.UDPTunnel->packet.data = malloc(size);
518         if (msg->payload.UDPTunnel->packet.data == NULL)
519                 Log_fatal("Out of memory");
520         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
521         msg->payload.UDPTunnel->packet.len = size;
522         return msg;
523 }
524
525 message_t *Msg_networkToMessage(uint8_t *data, int size)
526 {
527         message_t *msg = NULL;
528         uint8_t *msgData = &data[6];
529         int messageType, msgLen;
530
531         Msg_getPreamble(data, &messageType, &msgLen);
532
533         Log_debug("Message type %d size %d", messageType, msgLen);
534         //dumpmsg(data, size);
535         
536         switch (messageType) {
537         case Version:
538         {
539                 msg = Msg_create_nopayload(Version);
540                 msg->unpacked = true;
541                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
542                 if (msg->payload.version == NULL)
543                         goto err_out;
544                 break;
545         }
546         case UDPTunnel: /* Non-standard handling of tunneled voice data */
547         {
548                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
549                 break;
550         }
551         case Authenticate:
552         {
553                 msg = Msg_create_nopayload(Authenticate);
554                 msg->unpacked = true;
555                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
556                 if (msg->payload.authenticate == NULL)
557                         goto err_out;
558                 break;
559         }
560         case Ping:
561         {
562                 msg = Msg_create_nopayload(Ping);
563                 msg->unpacked = true;
564                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
565                 if (msg->payload.ping == NULL)
566                         goto err_out;
567                 break;
568         }
569         case Reject:
570         {
571                 msg = Msg_create_nopayload(Reject);
572                 msg->unpacked = true;
573                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
574                 if (msg->payload.reject == NULL)
575                         goto err_out;
576                 break;
577         }
578         case ServerSync:
579         {
580                 msg = Msg_create_nopayload(ServerSync);
581                 msg->unpacked = true;
582                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
583                 if (msg->payload.serverSync == NULL)
584                         goto err_out;
585                 break;
586         }
587         case TextMessage:
588         {
589                 msg = Msg_create_nopayload(TextMessage);
590                 msg->unpacked = true;
591                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
592                 if (msg->payload.textMessage == NULL)
593                         goto err_out;
594                 break;
595         }
596         case PermissionDenied:
597         {
598                 msg = Msg_create_nopayload(PermissionDenied);
599                 msg->unpacked = true;
600                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
601                 if (msg->payload.permissionDenied == NULL)
602                         goto err_out;
603                 break;
604         }
605         case CryptSetup:
606         {
607                 msg = Msg_create_nopayload(CryptSetup);
608                 msg->unpacked = true;
609                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
610                 if (msg->payload.cryptSetup == NULL)
611                         goto err_out;
612                 break;
613         }
614         case UserList:
615         {
616                 msg = Msg_create_nopayload(UserList);
617                 msg->unpacked = true;
618                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
619                 if (msg->payload.userList == NULL)
620                         goto err_out;
621                 break;
622         }
623         case UserState:
624         {
625                 msg = Msg_create_nopayload(UserState);
626                 msg->unpacked = true;
627                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
628                 if (msg->payload.userState == NULL)
629                         goto err_out;
630                 break;
631         }
632         case ChannelState:
633         {
634                 msg = Msg_create_nopayload(ChannelState);
635                 msg->unpacked = true;
636                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
637                 if (msg->payload.channelState == NULL)
638                         goto err_out;
639                 break;
640         }
641         case VoiceTarget:
642         {
643                 msg = Msg_create_nopayload(VoiceTarget);
644                 msg->unpacked = true;
645                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
646                 if (msg->payload.voiceTarget == NULL)
647                         goto err_out;
648                 break;
649         }
650         case CodecVersion:
651         {
652                 msg = Msg_create_nopayload(CodecVersion);
653                 msg->unpacked = true;
654                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
655                 if (msg->payload.codecVersion == NULL)
656                         goto err_out;
657                 break;
658         }
659         case PermissionQuery:
660         {
661                 msg = Msg_create_nopayload(PermissionQuery);
662                 msg->unpacked = true;
663                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
664                 if (msg->payload.permissionQuery == NULL)
665                         goto err_out;
666                 break;
667         }
668         case ChannelRemove:
669         {
670                 msg = Msg_create_nopayload(ChannelRemove);
671                 msg->unpacked = true;
672                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
673                 if (msg->payload.channelRemove == NULL)
674                         goto err_out;
675                 break;
676         }
677
678         default:
679                 Log_warn("Unsupported message %d", messageType);
680                 break;
681         }
682         return msg;
683         
684 err_out:
685         free(msg);
686         return NULL;
687 }