Update Mumble protocol to 1.2.3
[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 message_t *Msg_create_nopayload(messageType_t messageType);
45
46 static void Msg_addPreamble(uint8_t *buffer, uint16_t type, uint32_t len)
47 {       
48         buffer[1] = (type) & 0xff;
49         buffer[0] = (type >> 8) & 0xff;
50         
51         buffer[5] = (len) & 0xff;
52         buffer[4] = (len >> 8) & 0xff;
53         buffer[3] = (len >> 16) & 0xff;
54         buffer[2] = (len >> 24) & 0xff; 
55 }
56
57 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
58 {
59         uint16_t msgType;
60         uint32_t msgLen;
61         
62         msgType = buffer[1] | (buffer[0] << 8);
63         msgLen = buffer[5] | (buffer[4] << 8) | (buffer[3] << 16) | (buffer[2] << 24);
64         *type = (int)msgType;
65         *len = (int)msgLen;
66 }
67
68 #define MAX_MSGSIZE (BUFSIZE - PREAMBLE_SIZE)
69 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
70 {
71         int len;
72         uint8_t *bufptr = buffer + PREAMBLE_SIZE;
73                 
74         Log_debug("To net: msg type %d", msg->messageType);
75         switch (msg->messageType) {
76         case Version:
77                 len = mumble_proto__version__get_packed_size(msg->payload.version);
78                 if (len > MAX_MSGSIZE) {
79                         Log_warn("Too big tx message. Discarding");
80                         break;
81                 }
82                 Msg_addPreamble(buffer, msg->messageType, len);
83                 mumble_proto__version__pack(msg->payload.version, bufptr);
84                 break;
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");
88                         break;
89                 }
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);
93                 break;
94         case Authenticate:
95                 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
96                 if (len > MAX_MSGSIZE) {
97                         Log_warn("Too big tx message. Discarding");
98                         break;
99                         }
100                 Msg_addPreamble(buffer, msg->messageType, len);
101                 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
102                 break;
103         case Ping:
104                 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
105                 if (len > MAX_MSGSIZE) {
106                         Log_warn("Too big tx message. Discarding");
107                         break;
108                         }
109                 Msg_addPreamble(buffer, msg->messageType, len);
110                 mumble_proto__ping__pack(msg->payload.ping, bufptr);
111                 break;
112         case Reject:
113                 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
114                 if (len > MAX_MSGSIZE) {
115                         Log_warn("Too big tx message. Discarding");
116                         break;
117                         }
118                 Msg_addPreamble(buffer, msg->messageType, len);
119                 mumble_proto__reject__pack(msg->payload.reject, bufptr);
120                 break;
121         case ServerSync:
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");
125                         break;
126                         }
127                 Msg_addPreamble(buffer, msg->messageType, len);
128                 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
129                 break;
130         case TextMessage:
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");
134                         break;
135                         }
136                 Msg_addPreamble(buffer, msg->messageType, len);
137                 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
138                 break;
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");
143                         break;
144                         }
145                 Msg_addPreamble(buffer, msg->messageType, len);
146                 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
147                 break;
148         case CryptSetup:
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");
152                         break;
153                         }
154                 Msg_addPreamble(buffer, msg->messageType, len);
155                 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
156                 break;
157         case UserList:
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");
161                         break;
162                         }
163                 Msg_addPreamble(buffer, msg->messageType, len);
164                 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
165                 break;
166         case UserState:
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");
170                         break;
171                         }
172                 Msg_addPreamble(buffer, msg->messageType, len);
173                 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
174                 break;
175         case UserRemove:
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");
179                         break;
180                         }
181                 Msg_addPreamble(buffer, msg->messageType, len);
182                 mumble_proto__user_remove__pack(msg->payload.userRemove, bufptr);
183                 break;
184         case ChannelState:
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");
188                         break;
189                         }
190                 Msg_addPreamble(buffer, msg->messageType, len);
191                 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
192                 break;
193         case VoiceTarget:
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");
197                         break;
198                         }
199                 Msg_addPreamble(buffer, msg->messageType, len);
200                 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
201                 break;
202         case CodecVersion:
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");
206                         break;
207                         }
208                 Msg_addPreamble(buffer, msg->messageType, len);
209                 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
210                 break;
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");
215                         break;
216                         }
217                 Msg_addPreamble(buffer, msg->messageType, len);
218                 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
219                 break;
220         case ChannelRemove:
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");
224                         break;
225                         }
226                 Msg_addPreamble(buffer, msg->messageType, len);
227                 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
228                 break;
229         case UserStats:
230         {               
231                 len = mumble_proto__user_stats__get_packed_size(msg->payload.userStats);
232                 if (len > MAX_MSGSIZE) {
233                         Log_warn("Too big tx message. Discarding");
234                         break;
235                         }
236                 Msg_addPreamble(buffer, msg->messageType, len);
237                 mumble_proto__user_stats__pack(msg->payload.userStats, bufptr);
238                 break;
239         }
240         case ServerConfig:
241                 len = mumble_proto__server_config__get_packed_size(msg->payload.serverConfig);
242                 if (len > MAX_MSGSIZE) {
243                         Log_warn("Too big tx message. Discarding");
244                         break;
245                         }
246                 Msg_addPreamble(buffer, msg->messageType, len);
247                 mumble_proto__server_config__pack(msg->payload.serverConfig, bufptr);
248                 break;
249
250         default:
251                 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
252                 return 0;
253         }
254         return len + PREAMBLE_SIZE;
255 }
256
257 static message_t *Msg_create_nopayload(messageType_t messageType)
258 {
259         message_t *msg = malloc(sizeof(message_t));
260
261         if (msg == NULL)
262                 Log_fatal("Out of memory");
263         memset(msg, 0, sizeof(message_t));
264         msg->refcount = 1;
265         msg->messageType = messageType;
266         init_list_entry(&msg->node);
267         return msg;
268 }
269
270 message_t *Msg_create(messageType_t messageType)
271 {
272         message_t *msg = Msg_create_nopayload(messageType);
273         
274         switch (messageType) {
275         case Version:
276                 msg->payload.version = malloc(sizeof(MumbleProto__Version));
277                 mumble_proto__version__init(msg->payload.version);
278                 break;
279         case UDPTunnel:
280                 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
281                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
282                 break;
283         case Authenticate:
284                 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
285                 mumble_proto__authenticate__init(msg->payload.authenticate);
286                 break;
287         case Ping:
288                 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
289                 mumble_proto__ping__init(msg->payload.ping);
290                 break;
291         case Reject:
292                 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
293                 mumble_proto__reject__init(msg->payload.reject);
294                 break;
295         case ServerSync:
296                 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
297                 mumble_proto__server_sync__init(msg->payload.serverSync);
298                 break;
299         case TextMessage:
300                 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
301                 mumble_proto__text_message__init(msg->payload.textMessage);
302                 break;
303         case PermissionDenied:
304                 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
305                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
306                 break;
307         case CryptSetup:
308                 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
309                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
310                 break;
311         case UserList:
312                 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
313                 mumble_proto__user_list__init(msg->payload.userList);
314                 break;
315         case UserState:
316                 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
317                 mumble_proto__user_state__init(msg->payload.userState);
318                 break;
319         case ChannelState:
320                 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
321                 mumble_proto__channel_state__init(msg->payload.channelState);
322                 break;
323         case UserRemove:
324                 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
325                 mumble_proto__user_remove__init(msg->payload.userRemove);
326                 break;
327         case VoiceTarget:
328                 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
329                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
330                 break;
331         case CodecVersion:
332                 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
333                 mumble_proto__codec_version__init(msg->payload.codecVersion);
334                 break;
335         case PermissionQuery:
336                 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
337                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
338                 break;
339         case ChannelRemove:
340                 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
341                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
342                 break;
343         case UserStats:
344                 msg->payload.userStats = malloc(sizeof(MumbleProto__UserStats));
345                 mumble_proto__user_stats__init(msg->payload.userStats);
346                 
347                 msg->payload.userStats->from_client = malloc(sizeof(MumbleProto__UserStats__Stats));
348                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_client);
349
350                 msg->payload.userStats->from_server = malloc(sizeof(MumbleProto__UserStats__Stats));
351                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_server);
352
353                 msg->payload.userStats->version = malloc(sizeof(MumbleProto__Version));
354                 mumble_proto__version__init(msg->payload.userStats->version);
355                 
356                 if (!msg->payload.userStats || !msg->payload.userStats->from_client ||
357                         !msg->payload.userStats->from_server || !msg->payload.userStats->version)
358                         Log_fatal("Out of memory");
359                 break;
360         case ServerConfig:
361                 msg->payload.serverConfig = malloc(sizeof(MumbleProto__ServerConfig));
362                 mumble_proto__server_config__init(msg->payload.serverConfig);
363                 break;
364
365         default:
366                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
367                 break;
368         }
369
370         return msg;
371 }
372
373 void Msg_inc_ref(message_t *msg)
374 {
375         msg->refcount++;
376 }
377
378 void Msg_free(message_t *msg)
379 {
380         if (msg->refcount) msg->refcount--;
381         if (msg->refcount > 0)
382                 return;
383
384         switch (msg->messageType) {
385         case Version:
386                 if (msg->unpacked)
387                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
388                 else {
389                         if (msg->payload.version->release)
390                                 free(msg->payload.version->release);
391                         if (msg->payload.version->os)
392                                 free(msg->payload.version->os);
393                         if (msg->payload.version->os_version)
394                                 free(msg->payload.version->os_version);
395                         free(msg->payload.version);
396                 }
397                 break;
398         case UDPTunnel:
399                 if (msg->unpacked)
400                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
401                 else {
402                         free(msg->payload.UDPTunnel->packet.data);
403                         free(msg->payload.UDPTunnel);
404                 }
405                 break;
406         case Authenticate:
407                 if (msg->unpacked)
408                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
409                 else
410                         free(msg->payload.authenticate);
411                 break;
412         case Ping:
413                 if (msg->unpacked)
414                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
415                 else {
416                         free(msg->payload.ping);
417                 }
418                 break;
419         case Reject:
420                 if (msg->unpacked)
421                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
422                 else {
423                         free(msg->payload.reject->reason);
424                         free(msg->payload.reject);
425                 }
426                 break;
427         case ServerSync:
428                 if (msg->unpacked)
429                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
430                 else {
431                         free(msg->payload.serverSync->welcome_text);
432                         free(msg->payload.serverSync);
433                 }
434                 break;
435         case TextMessage:
436                 if (msg->unpacked)
437                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
438                 else {
439                         free(msg->payload.textMessage);
440                 }
441                 break;
442         case PermissionDenied:
443                 if (msg->unpacked)
444                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
445                 else {
446                         free(msg->payload.permissionDenied->reason);
447                         free(msg->payload.permissionDenied);
448                 }
449                 break;
450         case CryptSetup:
451                 if (msg->unpacked)
452                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
453                 else {
454                         free(msg->payload.cryptSetup);
455                 }
456                 break;
457         case UserList:
458                 if (msg->unpacked)
459                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
460                 else {
461                         free(msg->payload.userList);
462                 }
463                 break;
464         case UserState:
465                 if (msg->unpacked)
466                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
467                 else {
468                         free(msg->payload.userState->name);
469                         free(msg->payload.userState);
470                 }
471                 break;
472         case ChannelState:
473                 if (msg->unpacked)
474                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
475                 else {
476                         if (msg->payload.channelState->name)
477                                 free(msg->payload.channelState->name);
478                         if (msg->payload.channelState->description)
479                                 free(msg->payload.channelState->description);
480                         if (msg->payload.channelState->links)
481                                 free(msg->payload.channelState->links);
482                         free(msg->payload.channelState);
483                 }
484                 break;
485         case UserRemove:
486                 if (msg->unpacked)
487                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
488                 else {
489                         free(msg->payload.userRemove);
490                 }
491                 break;
492         case VoiceTarget:
493                 if (msg->unpacked)
494                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
495                 else {
496                         free(msg->payload.voiceTarget);
497                 }
498                 break;
499         case CodecVersion:
500                 if (msg->unpacked)
501                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
502                 else {
503                         free(msg->payload.codecVersion);
504                 }
505                 break;
506         case PermissionQuery:
507                 if (msg->unpacked)
508                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
509                 else {
510                         free(msg->payload.permissionQuery);
511                 }
512                 break;
513         case ChannelRemove:
514                 if (msg->unpacked)
515                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
516                 else {
517                         free(msg->payload.channelRemove);
518                 }
519                 break;
520         case UserStats:
521                 if (msg->unpacked)
522                         mumble_proto__user_stats__free_unpacked(msg->payload.userStats, NULL);
523                 else {
524                         if (msg->payload.userStats->from_client)
525                                 free(msg->payload.userStats->from_client);
526                         if (msg->payload.userStats->from_server)
527                                 free(msg->payload.userStats->from_server);
528                         if (msg->payload.userStats->version) {
529                                 if (msg->payload.userStats->version->release)
530                                         free(msg->payload.userStats->version->release);
531                                 if (msg->payload.userStats->version->os)
532                                         free(msg->payload.userStats->version->os);
533                                 if (msg->payload.userStats->version->os_version)
534                                         free(msg->payload.userStats->version->os_version);
535
536                                 free(msg->payload.userStats->version);
537                         }
538                         if (msg->payload.userStats->celt_versions)
539                                 free(msg->payload.userStats->celt_versions);
540                         if (msg->payload.userStats->certificates) {
541                                 if (msg->payload.userStats->certificates->data)
542                                         free(msg->payload.userStats->certificates->data);
543                                 free(msg->payload.userStats->certificates);
544                         }
545                         if (msg->payload.userStats->address.data)
546                                 free(msg->payload.userStats->address.data);
547
548                         free(msg->payload.userStats);
549                 }
550                 break;
551         case ServerConfig:
552                 if (msg->unpacked)
553                         mumble_proto__server_config__free_unpacked(msg->payload.serverConfig, NULL);
554                 else {
555                         free(msg->payload.serverConfig);
556                 }
557                 break;
558
559         default:
560                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
561                 break;
562         }
563         free(msg);
564 }
565
566 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
567 {
568         message_t *msg = NULL;
569         
570         msg = Msg_create_nopayload(UDPTunnel);
571         msg->unpacked = false;
572         msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
573         if (msg->payload.UDPTunnel == NULL)
574                 Log_fatal("Out of memory");
575         msg->payload.UDPTunnel->packet.data = malloc(size);
576         if (msg->payload.UDPTunnel->packet.data == NULL)
577                 Log_fatal("Out of memory");
578         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
579         msg->payload.UDPTunnel->packet.len = size;
580         return msg;
581 }
582
583 message_t *Msg_networkToMessage(uint8_t *data, int size)
584 {
585         message_t *msg = NULL;
586         uint8_t *msgData = &data[6];
587         int messageType, msgLen;
588
589         Msg_getPreamble(data, &messageType, &msgLen);
590
591         Log_debug("Message type %d size %d", messageType, msgLen);
592         //dumpmsg(data, size);
593         
594         switch (messageType) {
595         case Version:
596         {
597                 msg = Msg_create_nopayload(Version);
598                 msg->unpacked = true;
599                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
600                 if (msg->payload.version == NULL)
601                         goto err_out;
602                 break;
603         }
604         case UDPTunnel: /* Non-standard handling of tunneled voice data */
605         {
606                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
607                 break;
608         }
609         case Authenticate:
610         {
611                 msg = Msg_create_nopayload(Authenticate);
612                 msg->unpacked = true;
613                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
614                 if (msg->payload.authenticate == NULL)
615                         goto err_out;
616                 break;
617         }
618         case Ping:
619         {
620                 msg = Msg_create_nopayload(Ping);
621                 msg->unpacked = true;
622                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
623                 if (msg->payload.ping == NULL)
624                         goto err_out;
625                 break;
626         }
627         case Reject:
628         {
629                 msg = Msg_create_nopayload(Reject);
630                 msg->unpacked = true;
631                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
632                 if (msg->payload.reject == NULL)
633                         goto err_out;
634                 break;
635         }
636         case ServerSync:
637         {
638                 msg = Msg_create_nopayload(ServerSync);
639                 msg->unpacked = true;
640                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
641                 if (msg->payload.serverSync == NULL)
642                         goto err_out;
643                 break;
644         }
645         case TextMessage:
646         {
647                 msg = Msg_create_nopayload(TextMessage);
648                 msg->unpacked = true;
649                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
650                 if (msg->payload.textMessage == NULL)
651                         goto err_out;
652                 break;
653         }
654         case PermissionDenied:
655         {
656                 msg = Msg_create_nopayload(PermissionDenied);
657                 msg->unpacked = true;
658                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
659                 if (msg->payload.permissionDenied == NULL)
660                         goto err_out;
661                 break;
662         }
663         case CryptSetup:
664         {
665                 msg = Msg_create_nopayload(CryptSetup);
666                 msg->unpacked = true;
667                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
668                 if (msg->payload.cryptSetup == NULL)
669                         goto err_out;
670                 break;
671         }
672         case UserList:
673         {
674                 msg = Msg_create_nopayload(UserList);
675                 msg->unpacked = true;
676                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
677                 if (msg->payload.userList == NULL)
678                         goto err_out;
679                 break;
680         }
681         case UserState:
682         {
683                 msg = Msg_create_nopayload(UserState);
684                 msg->unpacked = true;
685                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
686                 if (msg->payload.userState == NULL)
687                         goto err_out;
688                 break;
689         }
690         case ChannelState:
691         {
692                 msg = Msg_create_nopayload(ChannelState);
693                 msg->unpacked = true;
694                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
695                 if (msg->payload.channelState == NULL)
696                         goto err_out;
697                 break;
698         }
699         case VoiceTarget:
700         {
701                 msg = Msg_create_nopayload(VoiceTarget);
702                 msg->unpacked = true;
703                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
704                 if (msg->payload.voiceTarget == NULL)
705                         goto err_out;
706                 break;
707         }
708         case CodecVersion:
709         {
710                 msg = Msg_create_nopayload(CodecVersion);
711                 msg->unpacked = true;
712                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
713                 if (msg->payload.codecVersion == NULL)
714                         goto err_out;
715                 break;
716         }
717         case PermissionQuery:
718         {
719                 msg = Msg_create_nopayload(PermissionQuery);
720                 msg->unpacked = true;
721                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
722                 if (msg->payload.permissionQuery == NULL)
723                         goto err_out;
724                 break;
725         }
726         case ChannelRemove:
727         {
728                 msg = Msg_create_nopayload(ChannelRemove);
729                 msg->unpacked = true;
730                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
731                 if (msg->payload.channelRemove == NULL)
732                         goto err_out;
733                 break;
734         }
735         case UserStats:
736         {
737                 msg = Msg_create_nopayload(UserStats);
738                 msg->unpacked = true;
739                 msg->payload.userStats = mumble_proto__user_stats__unpack(NULL, msgLen, msgData);
740                 if (msg->payload.userStats == NULL)
741                         goto err_out;
742                 break;
743         }
744
745         default:
746                 Log_warn("Unsupported message %d", messageType);
747                 break;
748         }
749         return msg;
750         
751 err_out:
752         free(msg);
753         return NULL;
754 }