X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fclient.c;h=e4936e2419ef15f6091ceaa6bddd73ab25e5e9d6;hb=76f6cc6fd2eecb29f265226e43408a0d9ad41174;hp=963ec4dd5fb8b1b62a4acb1d99fa59500cd00c33;hpb=4c75c8f9eb45c0a696f992c277dcc8ffb77fa3ba;p=umurmur.git diff --git a/src/client.c b/src/client.c index 963ec4d..e4936e2 100644 --- a/src/client.c +++ b/src/client.c @@ -1,5 +1,5 @@ -/* Copyright (C) 2009-2010, Martin Johansson - Copyright (C) 2005-2010, Thorvald Natvig +/* Copyright (C) 2009-2011, Martin Johansson + Copyright (C) 2005-2011, Thorvald Natvig All rights reserved. @@ -146,6 +146,52 @@ codec_t *Client_codec_iterate(client_t *client, codec_t **codec_itr) 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; @@ -200,7 +246,7 @@ void recheckCodecVersions() // 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; @@ -211,8 +257,8 @@ void recheckCodecVersions() 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); @@ -270,6 +316,7 @@ int Client_add(int fd, struct sockaddr_in *remote) 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++; @@ -309,6 +356,7 @@ void Client_free(client_t *client) } Client_codec_free(client); Voicetarget_free_all(client); + Client_token_free(client); list_del(&client->node); if (client->ssl) @@ -354,10 +402,10 @@ int Client_read_fd(int fd) 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) @@ -457,10 +505,10 @@ int Client_write_fd(int fd) 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) @@ -505,6 +553,15 @@ 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) { @@ -577,6 +634,29 @@ int Client_send_message_except(client_t *client, message_t *msg) 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) && @@ -658,7 +738,6 @@ int Client_read_udp() memcpy(&itr->remote_udp, &from, sizeof(struct sockaddr_in)); break; } - else Log_warn("Bad cryptstate from peer"); } } /* while */ }