-/* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
- Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
+/* Copyright (C) 2009-2011, Martin Johansson <martin@fatbob.nu>
+ Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
All rights reserved.
return cd;
}
+void Client_token_add(client_t *client, char *token_string)
+{
+ token_t *token;
+
+ if (client->tokencount >= MAX_TOKENS)
+ return;
+ token = malloc(sizeof(token_t));
+ if (token == NULL)
+ Log_fatal("Out of memory");
+ init_list_entry(&token->node);
+ token->token = strdup(token_string);
+ if (token->token == NULL)
+ Log_fatal("Out of memory");
+ list_add_tail(&token->node, &client->tokens);
+ client->tokencount++;
+}
+
+bool_t Client_token_match(client_t *client, char *str)
+{
+ token_t *token;
+ struct dlist *itr;
+
+ if (list_empty(&client->tokens))
+ return false;
+ list_iterate(itr, &client->tokens) {
+ token = list_get_entry(itr, token_t, node);
+ if (strncasecmp(token->token, str, MAX_TOKENSIZE) == 0)
+ return true;
+ }
+ return false;
+}
+
+void Client_token_free(client_t *client)
+{
+ struct dlist *itr, *save;
+ token_t *token;
+
+ list_iterate_safe(itr, save, &client->tokens) {
+ token = list_get_entry(itr, token_t, node);
+ list_del(&token->node);
+ free(token->token);
+ free(token);
+ }
+ client->tokencount = 0;
+}
+
void recheckCodecVersions()
{
client_t *client_itr = NULL;
// it as alpha and announce it. If another codec now got the
// majority set it as the opposite of the currently valid bPreferAlpha
// and announce it.
- if (version == (uint32_t)0x8000000a)
+ if (version == (uint32_t)0x8000000b)
bPreferAlpha = true;
else
bPreferAlpha = ! bPreferAlpha;
iCodecBeta = version;
sendmsg = Msg_create(CodecVersion);
- sendmsg->payload.codecVersion->alpha = version;
- sendmsg->payload.codecVersion->beta = version;
+ sendmsg->payload.codecVersion->alpha = iCodecAlpha;
+ sendmsg->payload.codecVersion->beta = iCodecBeta;
sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
Client_send_message_except(NULL, sendmsg);
init_list_entry(&newclient->node);
init_list_entry(&newclient->voicetargets);
init_list_entry(&newclient->codecs);
+ init_list_entry(&newclient->tokens);
list_add_tail(&newclient->node, &clients);
clientcount++;
}
Client_codec_free(client);
Voicetarget_free_all(client);
+ Client_token_free(client);
list_del(&client->node);
if (client->ssl)
break;
}
}
- if (client == NULL)
- Log_fatal("No client found for fd %d", fd);
-
- return Client_read(client);
+ if (client != NULL)
+ return Client_read(client);
+ else
+ return -1;
}
int Client_read(client_t *client)
break;
}
}
- if (client == NULL)
- Log_fatal("No client found for fd %d", fd);
- Client_write(client);
- return 0;
+ if (client != NULL)
+ return Client_write(client);
+ else
+ return -1;
}
int Client_write(client_t *client)
return 0;
}
+int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
+{
+ if ((version == 0) || (client->version >= version) ||
+ ((version & 0x80000000) && (client->version < (~version))))
+ return Client_send_message(client, msg);
+ else
+ Msg_free(msg);
+}
+
int Client_send_message(client_t *client, message_t *msg)
{
if (!client->authenticated && msg->messageType != Version) {
return 0;
}
+int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
+{
+ client_t *itr = NULL;
+ int count = 0;
+
+ Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
+ while (Client_iterate(&itr) != NULL) {
+ if (itr != client) {
+ if (count++ > 0)
+ Msg_inc_ref(msg); /* One extra reference for each new copy */
+ Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount);
+ Client_send_message_ver(itr, msg, version);
+ }
+ }
+ Msg_free(msg); /* Free our reference to the message */
+
+ if (count == 0)
+ Msg_free(msg); /* If only 1 client is connected then no message is passed
+ * to Client_send_message(). Free it here. */
+
+ return 0;
+}
+
static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
{
if (CryptState_isValid(&client->cryptState) &&
memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in));
break;
}
- else Log_warn("Bad cryptstate from peer");
}
} /* while */
}