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