704f20dcb72d80ea160dad76c6f0d08c10663fd4
[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
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         case BanList:
251                 len = mumble_proto__ban_list__get_packed_size(msg->payload.banList);
252                 if (len > MAX_MSGSIZE) {
253                         Log_warn("Too big tx message. Discarding");
254                         break;
255                         }
256                 Msg_addPreamble(buffer, msg->messageType, len);
257                 Log_debug("Msg_MessageToNetwork: BanList size %d", len);
258                 mumble_proto__ban_list__pack(msg->payload.banList, bufptr);
259                 break;
260         default:
261                 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
262                 return 0;
263         }
264         return len + PREAMBLE_SIZE;
265 }
266
267 static message_t *Msg_create_nopayload(messageType_t messageType)
268 {
269         message_t *msg = malloc(sizeof(message_t));
270
271         if (msg == NULL)
272                 Log_fatal("Out of memory");
273         memset(msg, 0, sizeof(message_t));
274         msg->refcount = 1;
275         msg->messageType = messageType;
276         init_list_entry(&msg->node);
277         return msg;
278 }
279
280 message_t *Msg_create(messageType_t messageType)
281 {
282         message_t *msg = Msg_create_nopayload(messageType);
283         int i;
284
285         switch (messageType) {
286         case Version:
287                 msg->payload.version = malloc(sizeof(MumbleProto__Version));
288                 mumble_proto__version__init(msg->payload.version);
289                 break;
290         case UDPTunnel:
291                 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
292                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
293                 break;
294         case Authenticate:
295                 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
296                 mumble_proto__authenticate__init(msg->payload.authenticate);
297                 break;
298         case Ping:
299                 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
300                 mumble_proto__ping__init(msg->payload.ping);
301                 break;
302         case Reject:
303                 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
304                 mumble_proto__reject__init(msg->payload.reject);
305                 break;
306         case ServerSync:
307                 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
308                 mumble_proto__server_sync__init(msg->payload.serverSync);
309                 break;
310         case TextMessage:
311                 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
312                 mumble_proto__text_message__init(msg->payload.textMessage);
313                 break;
314         case PermissionDenied:
315                 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
316                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
317                 break;
318         case CryptSetup:
319                 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
320                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
321                 break;
322         case UserList:
323                 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
324                 mumble_proto__user_list__init(msg->payload.userList);
325                 break;
326         case UserState:
327                 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
328                 mumble_proto__user_state__init(msg->payload.userState);
329                 break;
330         case ChannelState:
331                 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
332                 mumble_proto__channel_state__init(msg->payload.channelState);
333                 break;
334         case UserRemove:
335                 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
336                 mumble_proto__user_remove__init(msg->payload.userRemove);
337                 break;
338         case VoiceTarget:
339                 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
340                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
341                 break;
342         case CodecVersion:
343                 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
344                 mumble_proto__codec_version__init(msg->payload.codecVersion);
345                 break;
346         case PermissionQuery:
347                 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
348                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
349                 break;
350         case ChannelRemove:
351                 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
352                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
353                 break;
354         case UserStats:
355                 msg->payload.userStats = malloc(sizeof(MumbleProto__UserStats));
356                 mumble_proto__user_stats__init(msg->payload.userStats);
357
358                 msg->payload.userStats->from_client = malloc(sizeof(MumbleProto__UserStats__Stats));
359                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_client);
360
361                 msg->payload.userStats->from_server = malloc(sizeof(MumbleProto__UserStats__Stats));
362                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_server);
363
364                 msg->payload.userStats->version = malloc(sizeof(MumbleProto__Version));
365                 mumble_proto__version__init(msg->payload.userStats->version);
366
367                 if (!msg->payload.userStats || !msg->payload.userStats->from_client ||
368                         !msg->payload.userStats->from_server || !msg->payload.userStats->version)
369                         Log_fatal("Out of memory");
370                 break;
371         case ServerConfig:
372                 msg->payload.serverConfig = malloc(sizeof(MumbleProto__ServerConfig));
373                 mumble_proto__server_config__init(msg->payload.serverConfig);
374                 break;
375
376         default:
377                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
378                 break;
379         }
380
381         return msg;
382 }
383
384 message_t *Msg_banList_create(int n_bans)
385 {
386         message_t *msg = Msg_create_nopayload(BanList);
387         int i;
388
389         msg->payload.banList = malloc(sizeof(MumbleProto__BanList));
390         if (msg->payload.banList == NULL)
391                 Log_fatal("Out of memory");
392         memset(msg->payload.banList, 0, sizeof(MumbleProto__BanList));
393         mumble_proto__ban_list__init(msg->payload.banList);
394         msg->payload.banList->n_bans = n_bans;
395         msg->payload.banList->bans = malloc(sizeof(MumbleProto__BanList__BanEntry *) * n_bans);
396         if (msg->payload.banList->bans == NULL)
397                 Log_fatal("Out of memory");
398         for (i = 0; i < n_bans; i++) {
399                 msg->payload.banList->bans[i] = malloc(sizeof(MumbleProto__BanList__BanEntry));
400                 if (msg->payload.banList->bans[i] == NULL)
401                         Log_fatal("Out of memory");
402                 memset(msg->payload.banList->bans[i], 0, sizeof(MumbleProto__BanList__BanEntry));
403                 mumble_proto__ban_list__ban_entry__init(msg->payload.banList->bans[i]);
404         }
405         return msg;
406 }
407
408 void Msg_banList_addEntry(message_t *msg, int index, uint8_t *address, uint32_t mask,
409                           char *name, char *hash, char *reason, char *start, uint32_t duration)
410 {
411         MumbleProto__BanList__BanEntry *entry = msg->payload.banList->bans[index];
412
413         entry->address.data = malloc(16);
414         if (!entry->address.data)
415                 Log_fatal("Out of memory");
416         memcpy(entry->address.data, address, 16);
417         entry->address.len = 16;
418         entry->mask = mask;
419         entry->name = strdup(name);
420         entry->hash = strdup(hash);
421         entry->reason = strdup(reason);
422         entry->start = strdup(start);
423         if (!entry->name || !entry->hash || !entry->reason || !entry->start)
424                 Log_fatal("Out of memory");
425
426         if (duration > 0) {
427                 entry->duration = duration;
428                 entry->has_duration = true;
429         }
430         Log_debug("Msg_banList_addEntry: %s %s %s %s %s",
431                 entry->name, entry->hash, entry->address.data, entry->reason, entry->start);
432 }
433
434 void Msg_banList_getEntry(message_t *msg, int index, uint8_t **address, uint32_t *mask,
435                           char **name, char **hash, char **reason, char **start, uint32_t *duration)
436 {
437         MumbleProto__BanList__BanEntry *entry = msg->payload.banList->bans[index];
438
439         *address =  entry->address.data;
440         *mask = entry->mask;
441         *name = entry->name;
442         *hash = entry->hash;
443         *reason = entry->reason;
444         *start = entry->start;
445         if (entry->has_duration)
446                 *duration = entry->duration;
447         else
448                 *duration = 0;
449 }
450
451
452 void Msg_inc_ref(message_t *msg)
453 {
454         msg->refcount++;
455 }
456
457 void Msg_free(message_t *msg)
458 {
459         int i;
460
461         if (msg->refcount) msg->refcount--;
462         if (msg->refcount > 0)
463                 return;
464
465         switch (msg->messageType) {
466         case Version:
467                 if (msg->unpacked)
468                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
469                 else {
470                         if (msg->payload.version->release)
471                                 free(msg->payload.version->release);
472                         if (msg->payload.version->os)
473                                 free(msg->payload.version->os);
474                         if (msg->payload.version->os_version)
475                                 free(msg->payload.version->os_version);
476                         free(msg->payload.version);
477                 }
478                 break;
479         case UDPTunnel:
480                 if (msg->unpacked)
481                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
482                 else {
483                         free(msg->payload.UDPTunnel->packet.data);
484                         free(msg->payload.UDPTunnel);
485                 }
486                 break;
487         case Authenticate:
488                 if (msg->unpacked)
489                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
490                 else
491                         free(msg->payload.authenticate);
492                 break;
493         case Ping:
494                 if (msg->unpacked)
495                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
496                 else {
497                         free(msg->payload.ping);
498                 }
499                 break;
500         case Reject:
501                 if (msg->unpacked)
502                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
503                 else {
504                         free(msg->payload.reject->reason);
505                         free(msg->payload.reject);
506                 }
507                 break;
508         case ServerSync:
509                 if (msg->unpacked)
510                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
511                 else {
512                         free(msg->payload.serverSync->welcome_text);
513                         free(msg->payload.serverSync);
514                 }
515                 break;
516         case TextMessage:
517                 if (msg->unpacked)
518                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
519                 else {
520                         if (msg->payload.textMessage->message)
521                                 free(msg->payload.textMessage->message);
522                         if (msg->payload.textMessage->session)
523                                 free(msg->payload.textMessage->session);
524                         if (msg->payload.textMessage->channel_id)
525                                 free(msg->payload.textMessage->channel_id);
526                         if (msg->payload.textMessage->tree_id)
527                                 free(msg->payload.textMessage->tree_id);
528                         free(msg->payload.textMessage);
529                 }
530                 break;
531         case PermissionDenied:
532                 if (msg->unpacked)
533                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
534                 else {
535                         free(msg->payload.permissionDenied->reason);
536                         free(msg->payload.permissionDenied);
537                 }
538                 break;
539         case CryptSetup:
540                 if (msg->unpacked)
541                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
542                 else {
543                         free(msg->payload.cryptSetup);
544                 }
545                 break;
546         case UserList:
547                 if (msg->unpacked)
548                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
549                 else {
550                         free(msg->payload.userList);
551                 }
552                 break;
553         case UserState:
554                 if (msg->unpacked)
555                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
556                 else {
557                         free(msg->payload.userState->name);
558                         free(msg->payload.userState);
559                 }
560                 break;
561         case ChannelState:
562                 if (msg->unpacked)
563                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
564                 else {
565                         if (msg->payload.channelState->name)
566                                 free(msg->payload.channelState->name);
567                         if (msg->payload.channelState->description)
568                                 free(msg->payload.channelState->description);
569                         if (msg->payload.channelState->links)
570                                 free(msg->payload.channelState->links);
571                         free(msg->payload.channelState);
572                 }
573                 break;
574         case UserRemove:
575                 if (msg->unpacked)
576                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
577                 else {
578                         free(msg->payload.userRemove);
579                 }
580                 break;
581         case VoiceTarget:
582                 if (msg->unpacked)
583                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
584                 else {
585                         free(msg->payload.voiceTarget);
586                 }
587                 break;
588         case CodecVersion:
589                 if (msg->unpacked)
590                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
591                 else {
592                         free(msg->payload.codecVersion);
593                 }
594                 break;
595         case PermissionQuery:
596                 if (msg->unpacked)
597                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
598                 else {
599                         free(msg->payload.permissionQuery);
600                 }
601                 break;
602         case ChannelRemove:
603                 if (msg->unpacked)
604                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
605                 else {
606                         free(msg->payload.channelRemove);
607                 }
608                 break;
609         case UserStats:
610                 if (msg->unpacked)
611                         mumble_proto__user_stats__free_unpacked(msg->payload.userStats, NULL);
612                 else {
613                         if (msg->payload.userStats->from_client)
614                                 free(msg->payload.userStats->from_client);
615                         if (msg->payload.userStats->from_server)
616                                 free(msg->payload.userStats->from_server);
617                         if (msg->payload.userStats->version) {
618                                 if (msg->payload.userStats->version->release)
619                                         free(msg->payload.userStats->version->release);
620                                 if (msg->payload.userStats->version->os)
621                                         free(msg->payload.userStats->version->os);
622                                 if (msg->payload.userStats->version->os_version)
623                                         free(msg->payload.userStats->version->os_version);
624
625                                 free(msg->payload.userStats->version);
626                         }
627                         if (msg->payload.userStats->celt_versions)
628                                 free(msg->payload.userStats->celt_versions);
629                         if (msg->payload.userStats->certificates) {
630                                 if (msg->payload.userStats->certificates->data)
631                                         free(msg->payload.userStats->certificates->data);
632                                 free(msg->payload.userStats->certificates);
633                         }
634                         if (msg->payload.userStats->address.data)
635                                 free(msg->payload.userStats->address.data);
636
637                         free(msg->payload.userStats);
638                 }
639                 break;
640         case ServerConfig:
641                 if (msg->unpacked)
642                         mumble_proto__server_config__free_unpacked(msg->payload.serverConfig, NULL);
643                 else {
644                         free(msg->payload.serverConfig);
645                 }
646                 break;
647         case BanList:
648                 if (msg->unpacked)
649                         mumble_proto__ban_list__free_unpacked(msg->payload.banList, NULL);
650                 else {
651                         for (i = 0; i < msg->payload.banList->n_bans; i++) {
652                                 free(msg->payload.banList->bans[i]->address.data);
653                                 free(msg->payload.banList->bans[i]->name);
654                                 free(msg->payload.banList->bans[i]->hash);
655                                 free(msg->payload.banList->bans[i]->reason);
656                                 free(msg->payload.banList->bans[i]->start);
657                                 free(msg->payload.banList->bans[i]);
658                         }
659                         free(msg->payload.banList->bans);
660                         free(msg->payload.banList);
661                 }
662                 break;
663
664         default:
665                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
666                 break;
667         }
668         free(msg);
669 }
670
671 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
672 {
673         message_t *msg = NULL;
674
675         msg = Msg_create_nopayload(UDPTunnel);
676         msg->unpacked = false;
677         msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
678         if (msg->payload.UDPTunnel == NULL)
679                 Log_fatal("Out of memory");
680         msg->payload.UDPTunnel->packet.data = malloc(size);
681         if (msg->payload.UDPTunnel->packet.data == NULL)
682                 Log_fatal("Out of memory");
683         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
684         msg->payload.UDPTunnel->packet.len = size;
685         return msg;
686 }
687
688 message_t *Msg_networkToMessage(uint8_t *data, int size)
689 {
690         message_t *msg = NULL;
691         uint8_t *msgData = &data[6];
692         int messageType, msgLen;
693
694         Msg_getPreamble(data, &messageType, &msgLen);
695
696         Log_debug("Message type %d size %d", messageType, msgLen);
697         //dumpmsg(data, size);
698
699         switch (messageType) {
700         case Version:
701         {
702                 msg = Msg_create_nopayload(Version);
703                 msg->unpacked = true;
704                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
705                 if (msg->payload.version == NULL)
706                         goto err_out;
707                 break;
708         }
709         case UDPTunnel: /* Non-standard handling of tunneled voice data */
710         {
711                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
712                 break;
713         }
714         case Authenticate:
715         {
716                 msg = Msg_create_nopayload(Authenticate);
717                 msg->unpacked = true;
718                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
719                 if (msg->payload.authenticate == NULL)
720                         goto err_out;
721                 break;
722         }
723         case Ping:
724         {
725                 msg = Msg_create_nopayload(Ping);
726                 msg->unpacked = true;
727                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
728                 if (msg->payload.ping == NULL)
729                         goto err_out;
730                 break;
731         }
732         case Reject:
733         {
734                 msg = Msg_create_nopayload(Reject);
735                 msg->unpacked = true;
736                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
737                 if (msg->payload.reject == NULL)
738                         goto err_out;
739                 break;
740         }
741         case ServerSync:
742         {
743                 msg = Msg_create_nopayload(ServerSync);
744                 msg->unpacked = true;
745                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
746                 if (msg->payload.serverSync == NULL)
747                         goto err_out;
748                 break;
749         }
750         case TextMessage:
751         {
752                 msg = Msg_create_nopayload(TextMessage);
753                 msg->unpacked = true;
754                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
755                 if (msg->payload.textMessage == NULL)
756                         goto err_out;
757                 break;
758         }
759         case PermissionDenied:
760         {
761                 msg = Msg_create_nopayload(PermissionDenied);
762                 msg->unpacked = true;
763                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
764                 if (msg->payload.permissionDenied == NULL)
765                         goto err_out;
766                 break;
767         }
768         case CryptSetup:
769         {
770                 msg = Msg_create_nopayload(CryptSetup);
771                 msg->unpacked = true;
772                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
773                 if (msg->payload.cryptSetup == NULL)
774                         goto err_out;
775                 break;
776         }
777         case UserList:
778         {
779                 msg = Msg_create_nopayload(UserList);
780                 msg->unpacked = true;
781                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
782                 if (msg->payload.userList == NULL)
783                         goto err_out;
784                 break;
785         }
786         case UserState:
787         {
788                 msg = Msg_create_nopayload(UserState);
789                 msg->unpacked = true;
790                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
791                 if (msg->payload.userState == NULL)
792                         goto err_out;
793                 break;
794         }
795         case ChannelState:
796         {
797                 msg = Msg_create_nopayload(ChannelState);
798                 msg->unpacked = true;
799                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
800                 if (msg->payload.channelState == NULL)
801                         goto err_out;
802                 break;
803         }
804         case VoiceTarget:
805         {
806                 msg = Msg_create_nopayload(VoiceTarget);
807                 msg->unpacked = true;
808                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
809                 if (msg->payload.voiceTarget == NULL)
810                         goto err_out;
811                 break;
812         }
813         case CodecVersion:
814         {
815                 msg = Msg_create_nopayload(CodecVersion);
816                 msg->unpacked = true;
817                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
818                 if (msg->payload.codecVersion == NULL)
819                         goto err_out;
820                 break;
821         }
822         case PermissionQuery:
823         {
824                 msg = Msg_create_nopayload(PermissionQuery);
825                 msg->unpacked = true;
826                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
827                 if (msg->payload.permissionQuery == NULL)
828                         goto err_out;
829                 break;
830         }
831         case ChannelRemove:
832         {
833                 msg = Msg_create_nopayload(ChannelRemove);
834                 msg->unpacked = true;
835                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
836                 if (msg->payload.channelRemove == NULL)
837                         goto err_out;
838                 break;
839         }
840         case UserStats:
841         {
842                 msg = Msg_create_nopayload(UserStats);
843                 msg->unpacked = true;
844                 msg->payload.userStats = mumble_proto__user_stats__unpack(NULL, msgLen, msgData);
845                 if (msg->payload.userStats == NULL)
846                         goto err_out;
847                 break;
848         }
849         case UserRemove:
850         {
851                 msg = Msg_create_nopayload(UserRemove);
852                 msg->unpacked = true;
853                 msg->payload.userRemove = mumble_proto__user_remove__unpack(NULL, msgLen, msgData);
854                 if (msg->payload.userRemove == NULL)
855                         goto err_out;
856                 break;
857         }
858         case BanList:
859         {
860                 msg = Msg_create_nopayload(BanList);
861                 msg->unpacked = true;
862                 msg->payload.banList = mumble_proto__ban_list__unpack(NULL, msgLen, msgData);
863                 if (msg->payload.banList == NULL)
864                         goto err_out;
865                 break;
866         }
867
868         default:
869                 Log_warn("Msg_networkToMessage: Unsupported message %d", messageType);
870                 break;
871         }
872         return msg;
873
874 err_out:
875         free(msg);
876         return NULL;
877 }