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