#include <stdlib.h>
#include <string.h>
#include "log.h"
+#include "memory.h"
#include "list.h"
#include "client.h"
#include "ssl.h"
#include "version.h"
#include "voicetarget.h"
#include "ban.h"
+#include "util.h"
extern char system_string[], version_string[];
bool_t bPreferAlpha;
extern int* udpsocks;
+extern bool_t hasv4;
void Client_init()
{
void Client_codec_add(client_t *client, int codec)
{
- codec_t *cd = malloc(sizeof(codec_t));
- if (cd == NULL)
- Log_fatal("Out of memory");
+ codec_t *cd = Memory_safeMalloc(1, sizeof(codec_t));
init_list_entry(&cd->node);
cd->codec = codec;
list_add_tail(&cd->node, &client->codecs);
if (client->tokencount >= MAX_TOKENS)
return;
- token = malloc(sizeof(token_t));
- if (token == NULL)
- Log_fatal("Out of memory");
+ token = Memory_safeMalloc(1, sizeof(token_t));
init_list_entry(&token->node);
token->token = strdup(token_string);
if (token->token == NULL)
client->tokencount++;
}
-bool_t Client_token_match(client_t *client, char *str)
+bool_t Client_token_match(client_t *client, char const *str)
{
token_t *token;
struct dlist *itr;
}
}
if (!found) {
- cd = malloc(sizeof(codec_t));
- if (!cd)
- Log_fatal("Out of memory");
+ cd = Memory_safeMalloc(1, sizeof(codec_t));
memset(cd, 0, sizeof(codec_t));
init_list_entry(&cd->node);
cd->codec = codec_itr->codec;
{
client_t* newclient;
message_t *sendmsg;
- char addressPresentation[INET6_ADDRSTRLEN];
- int port;
+ char* addressString = NULL;
-#warning FIX BANNING BEFORE RELEASE
-#if 0
- if (Ban_isBannedAddr((in_addr_t *)&remote->sin_addr)) {
- Log_info("Address %s banned. Disconnecting", inet_ntoa(remote->sin_addr));
+ if (Ban_isBannedAddr(remote)) {
+ addressString = Util_addressToString(remote);
+ Log_info("Address %s banned. Disconnecting", addressString);
+ free(addressString);
return -1;
}
-#endif
- if ((newclient = calloc(1, sizeof(client_t))) == NULL)
- Log_fatal("Out of memory (%s:%s)", __FILE__, __LINE__);
-
- if(remote->ss_family == AF_INET) {
- inet_ntop(AF_INET, &((struct sockaddr_in*)remote)->sin_addr, addressPresentation, INET6_ADDRSTRLEN);
- port = ntohs(((struct sockaddr_in*)remote)->sin_port);
- } else {
- inet_ntop(AF_INET6, &((struct sockaddr_in6*)remote)->sin6_addr, addressPresentation, INET6_ADDRSTRLEN);
- port = ntohs(((struct sockaddr_in6*)remote)->sin6_port);
- }
-
- memcpy(newclient->addressString, addressPresentation, INET6_ADDRSTRLEN);
+ newclient = Memory_safeCalloc(1, sizeof(client_t));
newclient->tcpfd = fd;
memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_storage));
newclient->ssl = SSLi_newconnection(&newclient->tcpfd, &newclient->SSLready);
if (newclient->ssl == NULL) {
- Log_warn("SSL negotiation failed with %s on port %d", addressPresentation, port);
+ addressString = Util_addressToString(remote);
+ Log_warn("SSL negotiation failed with %s on port %d", addressString, Util_addressToPort(remote));
+ free(addressString);
free(newclient);
return -1;
}
return Client_send_message(client, msg);
else
Msg_free(msg);
+ return -1;
}
int Client_send_message(client_t *client, message_t *msg)
uint32_t *tree_id;
message_t *sendmsg = NULL;
- message = malloc(strlen(text) + 1);
- if (!message)
- Log_fatal("Out of memory");
- tree_id = malloc(sizeof(uint32_t));
- if (!tree_id)
- Log_fatal("Out of memory");
+ message = Memory_safeMalloc(1, strlen(text) + 1);
+ tree_id = Memory_safeMalloc(1, sizeof(uint32_t));
*tree_id = 0;
sendmsg = Msg_create(TextMessage);
sendmsg->payload.textMessage->message = message;
memset(key, 0, KEY_LENGTH);
+ fromport = Util_addressToPort(&from);
+
if(from.ss_family == AF_INET) {
memcpy(fromaddress, &((struct sockaddr_in*)&from)->sin_addr, sizeof(in_addr_t));
- fromport = ntohs(((struct sockaddr_in*)&from)->sin_port);
memcpy(&key[0], &fromport, 2);
memcpy(&key[2], fromaddress, sizeof(in_addr_t));
} else {
memcpy(fromaddress, &((struct sockaddr_in6*)&from)->sin6_addr, 4 * sizeof(in_addr_t));
- fromport = ntohs(((struct sockaddr_in6*)&from)->sin6_port);
memcpy(&key[0], &fromport, 2);
memcpy(&key[2], fromaddress, 4 * sizeof(in_addr_t));
}
- if (len == 0) {
+ if (len <= 0)
return -1;
- } else if (len < 0) {
- return -1;
- } else if (len < 5) {
- // 4 bytes crypt header + type + session
- return 0;
- } else if (len > UDP_PACKET_SIZE) {
+ else if (len < 5 || len > UDP_PACKET_SIZE) /* 4 bytes crypt header + type + session */
return 0;
- }
- /* Ping packet */
+ /*
+ * Reply to ping packet
+ * The second and third uint32_t are the timestamp, which will be returned unmodified
+ */
if (len == 12 && *encrypted == 0) {
uint32_t *ping = (uint32_t *)encrypted;
ping[0] = htonl((uint32_t)PROTOCOL_VERSION);
- // 1 and 2 will be the timestamp, which we return unmodified.
ping[3] = htonl((uint32_t)clientcount);
ping[4] = htonl((uint32_t)getIntConf(MAX_CLIENTS));
ping[5] = htonl((uint32_t)getIntConf(MAX_BANDWIDTH));
if (memcmp(itraddress, fromaddress, addresslength) == 0) {
if (checkDecrypt(itr, encrypted, buffer, len)) {
memcpy(itr->key, key, KEY_LENGTH);
- Log_info_client(itr, "New UDP connection from %s on port %d", itr->addressString, fromport);
+ char* clientAddressString = Util_clientAddressToString(itr);
+ Log_info_client(itr, "New UDP connection from %s on port %d", clientAddressString, fromport);
+ free(clientAddressString);
memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_storage));
break;
}
itr->bUDP = true;
len -= 4; /* Adjust for crypt header */
msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
+
+ char *clientAddressString = NULL;
+
switch (msgType) {
case UDPVoiceSpeex:
case UDPVoiceCELTAlpha:
Client_send_udp(itr, buffer, len);
break;
default:
- Log_debug("Unknown UDP message type from %s port %d", itr->addressString, fromport);
+ clientAddressString = Util_clientAddressToString(itr);
+ Log_debug("Unknown UDP message type from %s port %d", clientAddressString, fromport);
+ free(clientAddressString);
break;
}
if (vt->channels[i].linked && !list_empty(&ch->channel_links)) {
struct dlist *ch_itr;
list_iterate(ch_itr, &ch->channel_links) {
+ channellist_t *chl;
channel_t *ch_link;
- ch_link = list_get_entry(ch_itr, channel_t, link_node);
+ chl = list_get_entry(ch_itr, channellist_t, node);
+ ch_link = chl->chan;
list_iterate(itr, &ch_link->clients) {
client_t *c;
c = list_get_entry(itr, client_t, chan_node);
static int Client_send_udp(client_t *client, uint8_t *data, int len)
{
uint8_t *buf, *mbuf;
- uint16_t clientport;
- int udpsock = (client->remote_udp.ss_family == AF_INET) ? udpsocks[0] : udpsocks[1];
- if (client->remote_udp.ss_family == AF_INET)
- clientport = ntohs(((struct sockaddr_in*)&client->remote_udp)->sin_port);
- else
- clientport = ntohs(((struct sockaddr_in6*)&client->remote_udp)->sin6_port);
+ int udpsock = (client->remote_udp.ss_family == AF_INET) ? udpsocks[0] : udpsocks[(hasv4) ? 1 : 0];
- if (clientport != 0 && CryptState_isValid(&client->cryptState) &&
+ if (Util_clientAddressToPortUDP(client) != 0 && CryptState_isValid(&client->cryptState) &&
client->bUDP) {
#if defined(__LP64__)
- buf = mbuf = malloc(len + 4 + 16);
+ buf = mbuf = Memory_safeMalloc(1, len + 4 + 16);
buf += 4;
#else
- mbuf = buf = malloc(len + 4);
+ mbuf = buf = Memory_safeMalloc(1, len + 4);
#endif
- if (mbuf == NULL)
- Log_fatal("Out of memory");
-
CryptState_encrypt(&client->cryptState, data, buf, len);
- if (client->remote_udp.ss_family == AF_INET)
- sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
- else
- sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in6));
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+ sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, client->remote_tcp.ss_len);
+#else
+ sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_storage));
+#endif
free(mbuf);
} else {