Use Memory_safeCalloc() to allocate zeroed memory.
[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(1, sizeof(MumbleProto__BanList__BanEntry *) * n_bans);
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                         if (msg->payload.version->release)
456                                 free(msg->payload.version->release);
457                         if (msg->payload.version->os)
458                                 free(msg->payload.version->os);
459                         if (msg->payload.version->os_version)
460                                 free(msg->payload.version->os_version);
461                         free(msg->payload.version);
462                 }
463                 break;
464         case UDPTunnel:
465                 if (msg->unpacked)
466                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
467                 else {
468                         free(msg->payload.UDPTunnel->packet.data);
469                         free(msg->payload.UDPTunnel);
470                 }
471                 break;
472         case Authenticate:
473                 if (msg->unpacked)
474                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
475                 else
476                         free(msg->payload.authenticate);
477                 break;
478         case Ping:
479                 if (msg->unpacked)
480                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
481                 else {
482                         free(msg->payload.ping);
483                 }
484                 break;
485         case Reject:
486                 if (msg->unpacked)
487                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
488                 else {
489                         free(msg->payload.reject->reason);
490                         free(msg->payload.reject);
491                 }
492                 break;
493         case ServerSync:
494                 if (msg->unpacked)
495                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
496                 else {
497                         free(msg->payload.serverSync->welcome_text);
498                         free(msg->payload.serverSync);
499                 }
500                 break;
501         case TextMessage:
502                 if (msg->unpacked)
503                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
504                 else {
505                         if (msg->payload.textMessage->message)
506                                 free(msg->payload.textMessage->message);
507                         if (msg->payload.textMessage->session)
508                                 free(msg->payload.textMessage->session);
509                         if (msg->payload.textMessage->channel_id)
510                                 free(msg->payload.textMessage->channel_id);
511                         if (msg->payload.textMessage->tree_id)
512                                 free(msg->payload.textMessage->tree_id);
513                         free(msg->payload.textMessage);
514                 }
515                 break;
516         case PermissionDenied:
517                 if (msg->unpacked)
518                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
519                 else {
520                         free(msg->payload.permissionDenied->reason);
521                         free(msg->payload.permissionDenied);
522                 }
523                 break;
524         case CryptSetup:
525                 if (msg->unpacked)
526                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
527                 else {
528                         free(msg->payload.cryptSetup);
529                 }
530                 break;
531         case UserList:
532                 if (msg->unpacked)
533                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
534                 else {
535                         free(msg->payload.userList);
536                 }
537                 break;
538         case UserState:
539                 if (msg->unpacked)
540                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
541                 else {
542                         free(msg->payload.userState->name);
543                         free(msg->payload.userState);
544                 }
545                 break;
546         case ChannelState:
547                 if (msg->unpacked)
548                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
549                 else {
550                         if (msg->payload.channelState->name)
551                                 free(msg->payload.channelState->name);
552                         if (msg->payload.channelState->description)
553                                 free(msg->payload.channelState->description);
554                         if (msg->payload.channelState->links)
555                                 free(msg->payload.channelState->links);
556                         free(msg->payload.channelState);
557                 }
558                 break;
559         case UserRemove:
560                 if (msg->unpacked)
561                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
562                 else {
563                         free(msg->payload.userRemove);
564                 }
565                 break;
566         case VoiceTarget:
567                 if (msg->unpacked)
568                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
569                 else {
570                         free(msg->payload.voiceTarget);
571                 }
572                 break;
573         case CodecVersion:
574                 if (msg->unpacked)
575                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
576                 else {
577                         free(msg->payload.codecVersion);
578                 }
579                 break;
580         case PermissionQuery:
581                 if (msg->unpacked)
582                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
583                 else {
584                         free(msg->payload.permissionQuery);
585                 }
586                 break;
587         case ChannelRemove:
588                 if (msg->unpacked)
589                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
590                 else {
591                         free(msg->payload.channelRemove);
592                 }
593                 break;
594         case UserStats:
595                 if (msg->unpacked)
596                         mumble_proto__user_stats__free_unpacked(msg->payload.userStats, NULL);
597                 else {
598                         if (msg->payload.userStats->from_client)
599                                 free(msg->payload.userStats->from_client);
600                         if (msg->payload.userStats->from_server)
601                                 free(msg->payload.userStats->from_server);
602                         if (msg->payload.userStats->version) {
603                                 if (msg->payload.userStats->version->release)
604                                         free(msg->payload.userStats->version->release);
605                                 if (msg->payload.userStats->version->os)
606                                         free(msg->payload.userStats->version->os);
607                                 if (msg->payload.userStats->version->os_version)
608                                         free(msg->payload.userStats->version->os_version);
609
610                                 free(msg->payload.userStats->version);
611                         }
612                         if (msg->payload.userStats->celt_versions)
613                                 free(msg->payload.userStats->celt_versions);
614                         if (msg->payload.userStats->certificates) {
615                                 if (msg->payload.userStats->certificates->data)
616                                         free(msg->payload.userStats->certificates->data);
617                                 free(msg->payload.userStats->certificates);
618                         }
619                         if (msg->payload.userStats->address.data)
620                                 free(msg->payload.userStats->address.data);
621
622                         free(msg->payload.userStats);
623                 }
624                 break;
625         case ServerConfig:
626                 if (msg->unpacked)
627                         mumble_proto__server_config__free_unpacked(msg->payload.serverConfig, NULL);
628                 else {
629                         free(msg->payload.serverConfig);
630                 }
631                 break;
632         case BanList:
633                 if (msg->unpacked)
634                         mumble_proto__ban_list__free_unpacked(msg->payload.banList, NULL);
635                 else {
636                         for (i = 0; i < msg->payload.banList->n_bans; i++) {
637                                 free(msg->payload.banList->bans[i]->address.data);
638                                 free(msg->payload.banList->bans[i]->name);
639                                 free(msg->payload.banList->bans[i]->hash);
640                                 free(msg->payload.banList->bans[i]->reason);
641                                 free(msg->payload.banList->bans[i]->start);
642                                 free(msg->payload.banList->bans[i]);
643                         }
644                         free(msg->payload.banList->bans);
645                         free(msg->payload.banList);
646                 }
647                 break;
648
649         default:
650                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
651                 break;
652         }
653         free(msg);
654 }
655
656 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
657 {
658         message_t *msg = NULL;
659
660         msg = Msg_create_nopayload(UDPTunnel);
661         msg->unpacked = false;
662         msg->payload.UDPTunnel = Memory_safeMalloc(1, sizeof(struct _MumbleProto__UDPTunnel));
663         msg->payload.UDPTunnel->packet.data = Memory_safeMalloc(1, size);
664         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
665         msg->payload.UDPTunnel->packet.len = size;
666         return msg;
667 }
668
669 message_t *Msg_networkToMessage(uint8_t *data, int size)
670 {
671         message_t *msg = NULL;
672         uint8_t *msgData = &data[6];
673         int messageType, msgLen;
674
675         Msg_getPreamble(data, &messageType, &msgLen);
676
677         Log_debug("Message type %d size %d", messageType, msgLen);
678         //dumpmsg(data, size);
679
680         switch (messageType) {
681         case Version:
682         {
683                 msg = Msg_create_nopayload(Version);
684                 msg->unpacked = true;
685                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
686                 if (msg->payload.version == NULL)
687                         goto err_out;
688                 break;
689         }
690         case UDPTunnel: /* Non-standard handling of tunneled voice data */
691         {
692                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
693                 break;
694         }
695         case Authenticate:
696         {
697                 msg = Msg_create_nopayload(Authenticate);
698                 msg->unpacked = true;
699                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
700                 if (msg->payload.authenticate == NULL)
701                         goto err_out;
702                 break;
703         }
704         case Ping:
705         {
706                 msg = Msg_create_nopayload(Ping);
707                 msg->unpacked = true;
708                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
709                 if (msg->payload.ping == NULL)
710                         goto err_out;
711                 break;
712         }
713         case Reject:
714         {
715                 msg = Msg_create_nopayload(Reject);
716                 msg->unpacked = true;
717                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
718                 if (msg->payload.reject == NULL)
719                         goto err_out;
720                 break;
721         }
722         case ServerSync:
723         {
724                 msg = Msg_create_nopayload(ServerSync);
725                 msg->unpacked = true;
726                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
727                 if (msg->payload.serverSync == NULL)
728                         goto err_out;
729                 break;
730         }
731         case TextMessage:
732         {
733                 msg = Msg_create_nopayload(TextMessage);
734                 msg->unpacked = true;
735                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
736                 if (msg->payload.textMessage == NULL)
737                         goto err_out;
738                 break;
739         }
740         case PermissionDenied:
741         {
742                 msg = Msg_create_nopayload(PermissionDenied);
743                 msg->unpacked = true;
744                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
745                 if (msg->payload.permissionDenied == NULL)
746                         goto err_out;
747                 break;
748         }
749         case CryptSetup:
750         {
751                 msg = Msg_create_nopayload(CryptSetup);
752                 msg->unpacked = true;
753                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
754                 if (msg->payload.cryptSetup == NULL)
755                         goto err_out;
756                 break;
757         }
758         case UserList:
759         {
760                 msg = Msg_create_nopayload(UserList);
761                 msg->unpacked = true;
762                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
763                 if (msg->payload.userList == NULL)
764                         goto err_out;
765                 break;
766         }
767         case UserState:
768         {
769                 msg = Msg_create_nopayload(UserState);
770                 msg->unpacked = true;
771                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
772                 if (msg->payload.userState == NULL)
773                         goto err_out;
774                 break;
775         }
776         case ChannelState:
777         {
778                 msg = Msg_create_nopayload(ChannelState);
779                 msg->unpacked = true;
780                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
781                 if (msg->payload.channelState == NULL)
782                         goto err_out;
783                 break;
784         }
785         case VoiceTarget:
786         {
787                 msg = Msg_create_nopayload(VoiceTarget);
788                 msg->unpacked = true;
789                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
790                 if (msg->payload.voiceTarget == NULL)
791                         goto err_out;
792                 break;
793         }
794         case CodecVersion:
795         {
796                 msg = Msg_create_nopayload(CodecVersion);
797                 msg->unpacked = true;
798                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
799                 if (msg->payload.codecVersion == NULL)
800                         goto err_out;
801                 break;
802         }
803         case PermissionQuery:
804         {
805                 msg = Msg_create_nopayload(PermissionQuery);
806                 msg->unpacked = true;
807                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
808                 if (msg->payload.permissionQuery == NULL)
809                         goto err_out;
810                 break;
811         }
812         case ChannelRemove:
813         {
814                 msg = Msg_create_nopayload(ChannelRemove);
815                 msg->unpacked = true;
816                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
817                 if (msg->payload.channelRemove == NULL)
818                         goto err_out;
819                 break;
820         }
821         case UserStats:
822         {
823                 msg = Msg_create_nopayload(UserStats);
824                 msg->unpacked = true;
825                 msg->payload.userStats = mumble_proto__user_stats__unpack(NULL, msgLen, msgData);
826                 if (msg->payload.userStats == NULL)
827                         goto err_out;
828                 break;
829         }
830         case UserRemove:
831         {
832                 msg = Msg_create_nopayload(UserRemove);
833                 msg->unpacked = true;
834                 msg->payload.userRemove = mumble_proto__user_remove__unpack(NULL, msgLen, msgData);
835                 if (msg->payload.userRemove == NULL)
836                         goto err_out;
837                 break;
838         }
839         case BanList:
840         {
841                 msg = Msg_create_nopayload(BanList);
842                 msg->unpacked = true;
843                 msg->payload.banList = mumble_proto__ban_list__unpack(NULL, msgLen, msgData);
844                 if (msg->payload.banList == NULL)
845                         goto err_out;
846                 break;
847         }
848
849         default:
850                 Log_warn("Msg_networkToMessage: Unsupported message %d", messageType);
851                 break;
852         }
853         return msg;
854
855 err_out:
856         free(msg);
857         return NULL;
858 }