Fixed banning to work for both v4 and v6
[umurmur.git] / src / client.c
index e3787a4832d3c1486f3fe2a3779b345e1dddcd1b..dc8b1c2d330aa93de0f6851f1daae8252eaf4810 100644 (file)
@@ -8,13 +8,13 @@
    are met:
 
    - Redistributions of source code must retain the above copyright notice,
-     this list of conditions and the following disclaimer.
+   this list of conditions and the following disclaimer.
    - Redistributions in binary form must reproduce the above copyright notice,
-     this list of conditions and the following disclaimer in the documentation
-     and/or other materials provided with the distribution.
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
    - Neither the name of the Developers nor the names of its contributors may
-     be used to endorse or promote products derived from this software without
-     specific prior written permission.
+   be used to endorse or promote products derived from this software without
+   specific prior written permission.
 
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -27,7 +27,7 @@
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+   */
 #include <sys/poll.h>
 #include <sys/socket.h>
 #include <fcntl.h>
@@ -290,7 +290,7 @@ void recheckCodecVersions(client_t *connectingClient)
                client_itr = NULL;
                while (Client_iterate(&client_itr) != NULL) {
                        if ((client_itr->authenticated || client_itr == connectingClient) &&
-                           !client_itr->bOpus) {
+                               !client_itr->bOpus) {
                                Client_textmessage(client_itr, OPUS_WARN_SWITCHING);
                        }
                }
@@ -319,31 +319,28 @@ static int findFreeSessionId()
 
 int Client_add(int fd, struct sockaddr_storage *remote)
 {
-  client_t* newclient;
+       client_t* newclient;
        message_t *sendmsg;
-  char addressPresentation[INET6_ADDRSTRLEN];
-  int port;
+       char addressPresentation[INET6_ADDRSTRLEN];
+       int port;
 
-#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(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);
+       }
+
+       if (Ban_isBannedAddr(remote)) {
+               Log_info("Address %s banned. Disconnecting", addressPresentation);
                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);
+       memcpy(newclient->addressString, addressPresentation, INET6_ADDRSTRLEN);
 
        newclient->tcpfd = fd;
        memcpy(&newclient->remote_tcp, remote, sizeof(struct sockaddr_storage));
@@ -506,8 +503,8 @@ int Client_read(client_t *client)
                                 * 1. A valid size. The only message that is this big is UserState message with a big texture
                                 * 2. An invalid size = protocol error, e.g. connecting with a 1.1.x client
                                 */
-//                             Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
-//                                              client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
+                               //                Log_warn("Too big message received (%d bytes). Playing safe and disconnecting client %s:%d",
+                               //                         client->msgsize, inet_ntoa(client->remote_tcp.sin_addr), ntohs(client->remote_tcp.sin_port));
                                Client_free(client);
                                return -1;
                                /* client->rxcount = client->msgsize = 0; */
@@ -528,7 +525,7 @@ int Client_read(client_t *client)
                                return 0;
                        }
                        else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_ZERO_RETURN ||
-                                SSLi_get_error(client->ssl, rc) == 0) {
+                               SSLi_get_error(client->ssl, rc) == 0) {
                                Log_info_client(client, "Connection closed by peer");
                                Client_close(client);
                        }
@@ -538,7 +535,7 @@ int Client_read(client_t *client)
                                                Log_info_client(client, "Connection closed by peer");
                                        else
                                                Log_info_client(client,"Error: %s  - Closing connection (code %d)",
-                                                               strerror(errno));
+                                                       strerror(errno));
                                }
                                else if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_CONNRESET) {
                                        Log_info_client(client, "Connection reset by peer");
@@ -597,7 +594,7 @@ int Client_write(client_t *client)
                }
                else {
                        if (SSLi_get_error(client->ssl, rc) == SSLI_ERROR_SYSCALL) {
-                               Log_info_client(client, "Error: %s  - Closing connection", strerror(errno));
+                               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");
@@ -772,8 +769,8 @@ int Client_read_udp(int udpsock)
        uint8_t key[KEY_LENGTH];
        client_t *itr;
        UDPMessageType_t msgType;
-  uint8_t fromaddress[4 * sizeof(in_addr_t)];
-  uint16_t fromport;
+       uint8_t fromaddress[4 * sizeof(in_addr_t)];
+       uint16_t fromport;
 
 #if defined(__LP64__)
        uint8_t encbuff[UDP_PACKET_SIZE + 8];
@@ -785,19 +782,19 @@ int Client_read_udp(int udpsock)
 
        len = recvfrom(udpsock, encrypted, UDP_PACKET_SIZE, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
 
-  memset(key, 0, KEY_LENGTH);
+       memset(key, 0, KEY_LENGTH);
 
-  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(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) {
                return -1;
@@ -833,19 +830,19 @@ int Client_read_udp(int udpsock)
                }
        }
        if (itr == NULL) { /* Unknown peer */
-    struct sockaddr_storage itraddressstorage;
-    uint8_t itraddress[4 * sizeof(in_addr_t)];
-    int addresslength;
+               struct sockaddr_storage itraddressstorage;
+               uint8_t itraddress[4 * sizeof(in_addr_t)];
+               int addresslength;
 
                while (Client_iterate(&itr) != NULL) {
-      itraddressstorage = itr->remote_tcp;
-      if(itraddressstorage.ss_family == AF_INET) {
-        memcpy(itraddress, &((struct sockaddr_in*)&from)->sin_addr, sizeof(in_addr_t));
-        addresslength = sizeof(in_addr_t);
-      } else {
-        memcpy(itraddress, &((struct sockaddr_in6*)&from)->sin6_addr, 4 * sizeof(in_addr_t));
-        addresslength = 4 * sizeof(in_addr_t);
-      }
+                       itraddressstorage = itr->remote_tcp;
+                       if(itraddressstorage.ss_family == AF_INET) {
+                               memcpy(itraddress, &((struct sockaddr_in*)&from)->sin_addr, sizeof(in_addr_t));
+                               addresslength = sizeof(in_addr_t);
+                       } else {
+                               memcpy(itraddress, &((struct sockaddr_in6*)&from)->sin6_addr, 4 * sizeof(in_addr_t));
+                               addresslength = 4 * sizeof(in_addr_t);
+                       }
 
                        if (memcmp(itraddress, fromaddress, addresslength) == 0) {
                                if (checkDecrypt(itr, encrypted, buffer, len)) {
@@ -865,21 +862,21 @@ int Client_read_udp(int udpsock)
        len -= 4; /* Adjust for crypt header */
        msgType = (UDPMessageType_t)((buffer[0] >> 5) & 0x7);
        switch (msgType) {
-       case UDPVoiceSpeex:
-       case UDPVoiceCELTAlpha:
-       case UDPVoiceCELTBeta:
-               if (bOpus)
+               case UDPVoiceSpeex:
+               case UDPVoiceCELTAlpha:
+               case UDPVoiceCELTBeta:
+                       if (bOpus)
+                               break;
+               case UDPVoiceOpus:
+                       Client_voiceMsg(itr, buffer, len);
+                       break;
+               case UDPPing:
+                       Log_debug("UDP Ping reply len %d", len);
+                       Client_send_udp(itr, buffer, len);
+                       break;
+               default:
+                       Log_debug("Unknown UDP message type from %s port %d", itr->addressString, fromport);
                        break;
-       case UDPVoiceOpus:
-               Client_voiceMsg(itr, buffer, len);
-               break;
-       case UDPPing:
-               Log_debug("UDP Ping reply len %d", len);
-               Client_send_udp(itr, buffer, len);
-               break;
-       default:
-               Log_debug("Unknown UDP message type from %s port %d", itr->addressString, fromport);
-               break;
        }
 
 out:
@@ -955,7 +952,7 @@ int Client_voiceMsg(client_t *client, uint8_t *data, int len)
                        c = list_get_entry(itr, client_t, chan_node);
                        Client_send_voice(client, c, buffer, pds->offset + 1, poslen);
                }
-       } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
+       } else if ((vt = Voicetarget_get_id(client, target)) != NULL) { /* Targeted whisper */
                int i;
                channel_t *ch;
                /* Channels */
@@ -1025,13 +1022,13 @@ out:
 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];
+       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);
+       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);
 
        if (clientport != 0 && CryptState_isValid(&client->cryptState) &&
                client->bUDP) {
@@ -1046,7 +1043,11 @@ static int Client_send_udp(client_t *client, uint8_t *data, int len)
 
                CryptState_encrypt(&client->cryptState, data, buf, len);
 
-               sendto(udpsock, buf, len + 4, 0, (struct sockaddr *)&client->remote_udp, sizeof(struct sockaddr_in));
+#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 {