Fix unsafe client removal from list at timeout.
[umurmur.git] / src / client.c
index e4936e2419ef15f6091ceaa6bddd73ab25e5e9d6..9f7576eff20051feb3d96ca36fa53ae8c19799c2 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2009-2011, Martin Johansson <martin@fatbob.nu>
-   Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
+/* Copyright (C) 2009-2012, Martin Johansson <martin@fatbob.nu>
+   Copyright (C) 2005-2012, Thorvald Natvig <thorvald@natvig.com>
 
    All rights reserved.
 
@@ -45,6 +45,7 @@
 #include "channel.h"
 #include "version.h"
 #include "voicetarget.h"
+#include "ban.h"
 
 extern char system_string[], version_string[];
 
@@ -90,9 +91,9 @@ int Client_getfds(struct pollfd *pollfds)
 
 void Client_janitor()
 {
-       struct dlist *itr;
+       struct dlist *itr, *save;
        int bwTop = maxBandwidth + maxBandwidth / 4;
-       list_iterate(itr, &clients) {
+       list_iterate_safe(itr, save, &clients) {
                client_t *c;
                c = list_get_entry(itr, client_t, node);
                Log_debug("Client %s BW available %d", c->username, c->availableBandwidth);
@@ -106,6 +107,7 @@ void Client_janitor()
                        Client_free(c);
                }
        }
+       Ban_pruneBanned();
 }
 
 void Client_codec_add(client_t *client, int codec)
@@ -288,7 +290,11 @@ int Client_add(int fd, struct sockaddr_in *remote)
 {
        client_t *newclient;
        message_t *sendmsg;
-       
+
+       if (Ban_isBannedAddr((in_addr_t *)&remote->sin_addr)) {
+               Log_info("Address %s banned. Disconnecting", inet_ntoa(remote->sin_addr));
+               return -1;
+       }
        newclient = malloc(sizeof(client_t));
        if (newclient == NULL)
                Log_fatal("Out of memory");
@@ -480,7 +486,10 @@ int Client_read(client_t *client)
                        }
                        else {
                                if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
-                                       Log_info_client(client, "Connection closed by peer");
+                                       Log_info_client(client,"Error: %s  - Closing connection", strerror(errno));
+                               }
+                               else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
+                                       Log_info_client(client, "Connection reset by peer");
                                }
                                else {
                                        Log_info_client(client, "SSL error: %d - Closing connection", SSLi_get_error(client->ssl, rc));
@@ -535,10 +544,15 @@ int Client_write(client_t *client)
                        return 0;
                }
                else {
-                       if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL)
-                               Log_warn("Client_write: Error: %s  - Closing connection", strerror(errno));
-                       else
-                               Log_warn("Client_write: SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
+                       if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
+                               Log_info_client(client, "Error: %s  - Closing connection", strerror(errno));
+                       }
+                       else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
+                               Log_info_client(client, "Connection reset by peer");
+                       }
+                       else {
+                               Log_info_client(client, "SSL error: %d - Closing connection.", SSLi_get_error(client->ssl, rc));
+                       }
                        Client_free(client);
                        return -1;
                }
@@ -769,7 +783,7 @@ out:
 
 static inline void Client_send_voice(client_t *src, client_t *dst, uint8_t *data, int len, int poslen)
 {
-       if (IS_AUTH(dst) && dst != src && !dst->deaf) {
+       if (IS_AUTH(dst) && dst != src && !dst->deaf && !dst->self_deaf) {
                if (poslen > 0 && /* Has positional data */
                        src->context != NULL && dst->context != NULL && /* ...both source and destination has context */
                        strcmp(src->context, dst->context) == 0) /* ...and the contexts match */
@@ -794,7 +808,7 @@ int Client_voiceMsg(client_t *client, uint8_t *data, int len)
        channel_t *ch = (channel_t *)client->channel;
        struct dlist *itr;
        
-       if (!client->authenticated || client->mute)
+       if (!client->authenticated || client->mute || client->self_mute)
                goto out;
        
        packetsize = 20 + 8 + 4 + len;