Parcourir la source

Included IpTunnel and did a refactoring of the codebase.

Caleb James DeLisle il y a 11 ans
Parent
commit
9b08100ec3
76 fichiers modifiés avec 811 ajouts et 343 suppressions
  1. 5 2
      admin/Admin.c
  2. 1 1
      admin/AdminClient.c
  3. 6 2
      admin/AdminLog.c
  4. 1 1
      admin/AuthorizedPasswords.c
  5. 1 1
      admin/Configurator.c
  6. 1 1
      admin/angel/Angel.c
  7. 1 1
      admin/angel/AngelInit.c
  8. 2 0
      admin/angel/Cjdns.c
  9. 1 1
      admin/angel/Waiter.c
  10. 6 2
      admin/angel/cjdroute2.c
  11. 3 3
      admin/test/Admin_test.c
  12. 6 4
      admin/testframework/AdminTestFramework.c
  13. 4 3
      benc/String.c
  14. 1 0
      benc/String.h
  15. 3 2
      benc/serialization/json/JsonBencSerializer.c
  16. 4 2
      benc/serialization/standard/StandardBencSerializer.c
  17. 4 3
      benc/serialization/standard/test/benc_serializeInteger_test.c
  18. 4 4
      benc/serialization/standard/test/benc_serializeList_test.c
  19. 10 11
      crypto/CryptoAuth.c
  20. 5 1
      crypto/test/CryptoAuth_test.c
  21. 14 11
      crypto/test/CryptoAuth_unit_test.c
  22. 1 1
      dht/AddressMapper.c
  23. 1 1
      dht/DHTModuleRegistry.c
  24. 1 1
      dht/ReplyModule.c
  25. 1 1
      dht/SerializationModule.c
  26. 5 5
      dht/dhtcore/DistanceNodeCollector.h
  27. 1 1
      dht/dhtcore/Janitor.c
  28. 7 6
      dht/dhtcore/LinkStateNodeCollector.h
  29. 8 6
      dht/dhtcore/NodeCollector.h
  30. 8 4
      dht/dhtcore/NodeStore.c
  31. 7 5
      dht/dhtcore/RouterModule.c
  32. 1 1
      dht/dhtcore/SearchStore.c
  33. 2 2
      dht/test/address_mapper_lru_test.c
  34. 1 1
      exception/Except.c
  35. 0 126
      interface/InterfaceMap.h
  36. 1 1
      interface/TUNConfigurator_FreeBSD.c
  37. 1 1
      interface/TUNConfigurator_Illumos.c
  38. 5 4
      interface/TUNConfigurator_Linux.c
  39. 1 1
      interface/TUNConfigurator_OSX.c
  40. 1 1
      interface/TUNConfigurator_OpenBSD.c
  41. 1 1
      interface/TUNInterface.c
  42. 1 1
      interface/TUNInterface_W32.c
  43. 0 1
      interface/UDPInterface_admin.c
  44. 4 1
      interface/test/UDPInterface_test.c
  45. 2 2
      io/test/FileReader_test.c
  46. 3 3
      memory/MallocAllocator.c
  47. 1 1
      memory/test/MallocAllocator_test.c
  48. 44 45
      net/DefaultInterfaceController.c
  49. 12 13
      net/Ducttape.c
  50. 3 0
      net/test/DefaultInterfaceController_test.c
  51. 1 1
      scripts/checkfiles.pl
  52. 5 3
      test/CryptoAddress_test.c
  53. 3 0
      test/cjdroute_injection_test.c
  54. 3 0
      test/cjdroute_routerPing_test.c
  55. 3 0
      tunnel/CMakeLists.txt
  56. 15 19
      tunnel/IpTunnel.c
  57. 0 1
      tunnel/IpTunnel_admin.c
  58. 27 0
      tunnel/test/CMakeLists.txt
  59. 151 0
      tunnel/test/IpTunnel_test.c
  60. 1 1
      util/AverageRoller.c
  61. 27 8
      util/Bits.h
  62. 3 2
      util/Identity.h
  63. 1 1
      util/Process_FreeBSD.c
  64. 1 1
      util/Process_Illumos.c
  65. 1 1
      util/Process_Linux.c
  66. 1 1
      util/Process_OSX.c
  67. 1 1
      util/Process_OpenBSD.c
  68. 1 1
      util/Process_W32.c
  69. 1 1
      util/Security.c
  70. 2 1
      util/Security_admin.c
  71. 3 1
      util/log/WriterLog.c
  72. 323 0
      util/platform/libc/string.h
  73. 20 0
      util/platform/libc/strlen.h
  74. 3 3
      util/test/Base32_test.c
  75. 6 2
      util/test/Hex_test.c
  76. 1 1
      util/test/Process_test.c

+ 5 - 2
admin/Admin.c

@@ -36,11 +36,14 @@
 #include "util/Time.h"
 #include "util/Timeout.h"
 
+#define string_strstr
+#define string_strcmp
+#define string_strlen
+#include "util/platform/libc/string.h"
 
 #include <crypto_hash_sha256.h>
 #include <event2/event.h>
 #include <limits.h>
-#include <string.h>
 #include <stdbool.h>
 #include <unistd.h>
 
@@ -256,7 +259,7 @@ static inline bool authValid(Dict* message, struct Message* messageBytes, struct
 
     crypto_hash_sha256(hash, messageBytes->bytes, messageBytes->length);
     Hex_encode(hashPtr, 64, hash, 32);
-    return memcmp(hashPtr, submittedHash->bytes, 64) == 0;
+    return Bits_memcmp(hashPtr, submittedHash->bytes, 64) == 0;
 }
 
 static bool checkArgs(Dict* args, struct Function* func, String* txid, struct Admin* admin)

+ 1 - 1
admin/AdminClient.c

@@ -19,12 +19,12 @@
 #include "io/ArrayWriter.h"
 #include "io/Reader.h"
 #include "io/Writer.h"
+#include "util/platform/libc/strlen.h"
 #include "util/Endian.h"
 #include "util/Errno.h"
 #include "util/Hex.h"
 
 #include <crypto_hash_sha256.h>
-#include <string.h>
 #include <unistd.h>
 #include <event2/event.h>
 

+ 6 - 2
admin/AdminLog.c

@@ -22,10 +22,14 @@
 #include "util/log/Log.h"
 #include "util/Hex.h"
 
+#define string_strcmp
+#define string_strrchr
+#define string_strlen
+#include "util/platform/libc/string.h"
+
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <string.h>
 #include <time.h>
 #include <stdbool.h>
 
@@ -255,7 +259,7 @@ static void unsubscribe(Dict* args, void* vcontext, String* txid)
     } else {
         error = "No such subscription.";
         for (int i = 0; i < (int)log->subscriptionCount; i++) {
-            if (!memcmp(streamId, log->subscriptions[i].streamId, 8)) {
+            if (!Bits_memcmp(streamId, log->subscriptions[i].streamId, 8)) {
                 removeSubscription(log, &log->subscriptions[i]);
                 error = "none";
                 break;

+ 1 - 1
admin/AuthorizedPasswords.c

@@ -15,7 +15,7 @@
 #include "admin/AuthorizedPasswords.h"
 #include "benc/Int.h"
 #include "memory/BufferAllocator.h"
-#include <string.h>
+#include "util/platform/libc/strlen.h"
 
 struct Context
 {

+ 1 - 1
admin/Configurator.c

@@ -18,10 +18,10 @@
 #include "benc/Dict.h"
 #include "benc/Int.h"
 #include "memory/Allocator.h"
+#include "util/platform/libc/strlen.h"
 #include "util/log/Log.h"
 
 #include <event2/event.h>
-#include <string.h>
 
 struct Context
 {

+ 1 - 1
admin/angel/Angel.c

@@ -18,6 +18,7 @@
 #include "interface/Interface.h"
 #include "interface/PipeInterface.h"
 #include "interface/Interface.h"
+#include "util/platform/libc/strlen.h"
 #include "util/Bits.h"
 #include "util/Errno.h"
 #include "util/log/Log.h"
@@ -27,7 +28,6 @@
 #include "wire/Error.h"
 
 #include <event2/event.h>
-#include <string.h>
 #include <unistd.h>
 
 struct AngelContext;

+ 1 - 1
admin/angel/AngelInit.c

@@ -30,6 +30,7 @@
 #include "exception/Jmp.h"
 #include "exception/Except.h"
 #include "util/events/EventBase.h"
+#include "util/platform/libc/strlen.h"
 #include "util/Bits.h"
 #include "util/Assert.h"
 #include "util/Errno.h"
@@ -43,7 +44,6 @@
 #include <unistd.h>
 #include <stdint.h>
 #include <event2/event.h>
-#include <string.h>
 
 #ifdef BSD
     #include <netinet/in.h>

+ 2 - 0
admin/angel/Cjdns.c

@@ -12,8 +12,10 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strcmp
 #include "admin/angel/AngelInit.h"
 #include "admin/angel/Core.h"
+#include "util/platform/libc/string.h"
 
 #include <stdio.h>
 #include <unistd.h>

+ 1 - 1
admin/angel/Waiter.c

@@ -22,7 +22,7 @@
 
 #include <event2/event.h>
 #include <unistd.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 
 struct Context
 {

+ 6 - 2
admin/angel/cjdroute2.c

@@ -12,6 +12,9 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strcmp
+#define string_strrchr
+#define string_strlen
 #include "admin/Admin.h"
 #include "admin/angel/Waiter.h"
 #include "admin/AuthorizedPasswords.h"
@@ -45,6 +48,7 @@
 #include "net/SwitchPinger.h"
 #include "net/SwitchPinger_admin.h"
 #include "switch/SwitchCore.h"
+#include "util/platform/libc/string.h"
 #include "util/events/EventBase.h"
 #include "util/Assert.h"
 #include "util/Base32.h"
@@ -293,7 +297,7 @@ static void reconf(struct event_base* eventbase,
     }
 
     struct sockaddr_storage addr;
-    memset(&addr, 0, sizeof(struct sockaddr_storage));
+    Bits_memset(&addr, 0, sizeof(struct sockaddr_storage));
     int addrLen = sizeof(struct sockaddr_storage);
     if (evutil_parse_sockaddr_port(address->bytes, (struct sockaddr*) &addr, &addrLen)) {
         Log_critical(logger, "Unable to parse [%s] as an ip address port, "
@@ -469,7 +473,7 @@ int main(int argc, char** argv)
     Dict* responseFromAngelAdmin = Dict_getDict(&responseFromAngel, String_CONST("admin"));
     adminBind = Dict_getString(responseFromAngelAdmin, String_CONST("bind"));
     struct sockaddr_storage adminAddr;
-    memset(&adminAddr, 0, sizeof(struct sockaddr_storage));
+    Bits_memset(&adminAddr, 0, sizeof(struct sockaddr_storage));
     int adminAddrLen = sizeof(struct sockaddr_storage);
     if (!adminBind) {
         Except_raise(eh, -1, "didn't get address and port back from angel");

+ 3 - 3
admin/test/Admin_test.c

@@ -19,9 +19,9 @@
 #include "benc/Int.h"
 #include "memory/Allocator.h"
 #include "util/Assert.h"
-#include <util/Errno.h>
+#include "util/Errno.h"
+#include "util/platform/libc/strlen.h"
 
-#include <string.h>
 #include <event2/event.h>
 
 struct Context {
@@ -75,7 +75,7 @@ static void slowClientIncoming(evutil_socket_t socket, short eventType, void* vc
         && ctx->slowClient.buf[ctx->slowClient.have-1] == 'e') {
 
         Log_error(ctx->framework->logger, "Got cookie response '%s'", ctx->slowClient.buf);
-        Assert_always(0 == memcmp("d6:cookie", ctx->slowClient.buf, 9));
+        Assert_always(0 == Bits_memcmp("d6:cookie", ctx->slowClient.buf, 9));
 
         event_base_loopexit(ctx->framework->eventBase, NULL);
     }

+ 6 - 4
admin/testframework/AdminTestFramework.c

@@ -37,8 +37,10 @@
 #include "util/log/WriterLog.h"
 #include "util/Pipe.h"
 #include "util/Process.h"
-
-#include <string.h>
+#define string_strlen
+#define string_strchr
+#define string_strcmp
+#include "util/platform/libc/string.h"
 #include <unistd.h>
 #include <event2/event.h>
 
@@ -106,7 +108,7 @@ static String* initAngel(int fromAngel,
     // This is angel->core data, we can throw this away.
     //Waiter_getData(buff, BUFFER_SZ, fromAngel, eventBase, NULL);
     //Log_info(logger, "Init message from angel to core: [%s]", buff);
-    memset(buff, 0, BUFFER_SZ);
+    Bits_memset(buff, 0, BUFFER_SZ);
 
     struct PipeInterface* pi =
         PipeInterface_new(FROM_ANGEL_AS_CORE, TO_ANGEL_AS_CORE, eventBase, logger, alloc, rand);
@@ -192,7 +194,7 @@ struct AdminTestFramework* AdminTestFramework_setUp(int argc, char** argv)
 
     struct sockaddr_storage addr;
     int addrLen = sizeof(struct sockaddr_storage);
-    memset(&addr, 0, sizeof(struct sockaddr_storage));
+    Bits_memset(&addr, 0, sizeof(struct sockaddr_storage));
     Assert_true(!evutil_parse_sockaddr_port(addrStr->bytes, (struct sockaddr*) &addr, &addrLen));
 
     struct AdminClient* client =

+ 4 - 3
benc/String.c

@@ -16,7 +16,8 @@
 #include "benc/String.h"
 #include "util/Bits.h"
 
-#include <string.h>
+#define string_strlen
+#include "util/platform/libc/string.h"
 #include <stdio.h>
 #include <stdarg.h>
 
@@ -35,7 +36,7 @@ String* String_newBinary(const char* bytes, size_t length, const struct Allocato
     if (bytes != NULL) {
         Bits_memcpy(copy, bytes, length);
     } else {
-        memset(copy, '\0', length);
+        Bits_memset(copy, '\0', length);
     }
     String* string = allocator->malloc(sizeof(String), allocator);
     string->len = length;
@@ -84,5 +85,5 @@ bool String_equals(const String* a, const String* b)
     if (a == NULL || b == NULL) {
         return a == NULL && b == NULL;
     }
-    return a->len == b->len && (memcmp(a->bytes, b->bytes, a->len) == 0);
+    return a->len == b->len && (Bits_memcmp(a->bytes, b->bytes, a->len) == 0);
 }

+ 1 - 0
benc/String.h

@@ -16,6 +16,7 @@
 #define String_H
 
 #include "memory/Allocator.h"
+#include "util/platform/libc/strlen.h"
 
 #include <stdbool.h>
 #include <stdarg.h>

+ 3 - 2
benc/serialization/json/JsonBencSerializer.c

@@ -17,11 +17,12 @@
 #include "io/Writer.h"
 #include "benc/Object.h"
 #include "benc/serialization/BencSerializer.h"
+#include "util/platform/libc/strlen.h"
+#include "util/Bits.h"
 #include "util/Errno.h"
 #include "util/Hex.h"
 
 #include <stdio.h>
-#include <string.h>
 #include <inttypes.h>
 #include <stdbool.h>
 
@@ -150,7 +151,7 @@ static int32_t serializeint64_t(const struct Writer* writer,
                                 int64_t integer)
 {
     char buffer[32];
-    memset(buffer, 0, 32);
+    Bits_memset(buffer, 0, 32);
 
     sprintf(buffer, "%" PRId64, integer);
 

+ 4 - 2
benc/serialization/standard/StandardBencSerializer.c

@@ -13,16 +13,18 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <stdio.h>
-#include <string.h>
 /* for parseint64_t */
 #include <limits.h>
 
+#include "util/Bits.h"
 #include "memory/Allocator.h"
 #include "io/Reader.h"
 #include "io/Writer.h"
 #include "benc/Object.h"
 #include "benc/serialization/BencSerializer.h"
 #include "util/Errno.h"
+#define string_strlen
+#include "util/platform/libc/string.h"
 
 static int32_t parseGeneric(const struct Reader* reader,
                             const struct Allocator* allocator,
@@ -40,7 +42,7 @@ static int32_t writeint64_t(const struct Writer* writer,
                             int64_t integer)
 {
     char buffer[32];
-    memset(buffer, 0, 32);
+    Bits_memset(buffer, 0, 32);
 
     sprintf(buffer, "%" PRId64, integer);
 

+ 4 - 3
benc/serialization/standard/test/benc_serializeInteger_test.c

@@ -12,9 +12,8 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <string.h>
-#include <stdio.h>
-
+#define string_strcmp
+#include "util/platform/libc/string.h"
 #include "memory/Allocator.h"
 #include "memory/BufferAllocator.h"
 #include "io/Reader.h"
@@ -25,6 +24,8 @@
 #include "benc/serialization/BencSerializer.h"
 #include "benc/serialization/standard/StandardBencSerializer.h"
 
+#include <stdio.h>
+
 int expect(char* str, struct Writer* writer, struct Reader* reader, int ret)
 {
     char buffer[32];

+ 4 - 4
benc/serialization/standard/test/benc_serializeList_test.c

@@ -12,9 +12,6 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <string.h>
-#include <stdio.h>
-
 #include "memory/Allocator.h"
 #include "memory/BufferAllocator.h"
 #include "io/Reader.h"
@@ -24,6 +21,9 @@
 #include "benc/Object.h"
 #include "benc/serialization/BencSerializer.h"
 #include "benc/serialization/standard/StandardBencSerializer.h"
+#include "util/Bits.h"
+
+#include <stdio.h>
 
 int parseEmptyList()
 {
@@ -42,7 +42,7 @@ int parseEmptyList()
     if (ret) {
         return ret;
     }
-    return memcmp(test, out, strlen(test));
+    return Bits_memcmp(test, out, strlen(test));
 }
 
 int main()

+ 10 - 11
crypto/CryptoAuth.c

@@ -37,7 +37,6 @@
 
 #include <stdint.h>
 #include <stdbool.h>
-#include <string.h>
 #include <event2/event.h>
 
 #ifdef WIN32
@@ -159,7 +158,7 @@ static inline struct CryptoAuth_Auth* getAuth(union Headers_AuthChallenge auth,
         return NULL;
     }
     for (uint32_t i = 0; i < context->passwordCount; i++) {
-        if (memcmp(auth.bytes, &context->passwords[i], Headers_AuthChallenge_KEYSIZE) == 0) {
+        if (Bits_memcmp(auth.bytes, &context->passwords[i], Headers_AuthChallenge_KEYSIZE) == 0) {
             return &context->passwords[i];
         }
     }
@@ -222,7 +221,7 @@ static inline int decryptRndNonce(uint8_t nonce[24],
     uint8_t* startAt = msg->bytes - 16;
     uint8_t paddingSpace[16];
     Bits_memcpyConst(paddingSpace, startAt, 16);
-    memset(startAt, 0, 16);
+    Bits_memset(startAt, 0, 16);
     if (crypto_box_curve25519xsalsa20poly1305_open_afternm(
             startAt, startAt, msg->length + 16, nonce, secret) != 0)
     {
@@ -251,7 +250,7 @@ static inline void encryptRndNonce(uint8_t nonce[24],
     // This function trashes 16 bytes of the padding so we will put it back
     uint8_t paddingSpace[16];
     Bits_memcpyConst(paddingSpace, startAt, 16);
-    memset(startAt, 0, 32);
+    Bits_memset(startAt, 0, 32);
     crypto_box_curve25519xsalsa20poly1305_afternm(
         startAt, startAt, msg->length + 32, nonce, secret);
 
@@ -483,7 +482,7 @@ static uint8_t encryptHandshake(struct Message* message, struct CryptoAuth_Wrapp
             Assert_true(!Bits_isZero(header->handshake.encryptedTempKey, 32));
             uint8_t myTempPubKey[32];
             crypto_scalarmult_curve25519_base(myTempPubKey, wrapper->secret);
-            Assert_true(!memcmp(header->handshake.encryptedTempKey, myTempPubKey, 32));
+            Assert_true(!Bits_memcmp(header->handshake.encryptedTempKey, myTempPubKey, 32));
         #endif
     } else {
         if (wrapper->nextNonce == 2) {
@@ -733,7 +732,7 @@ static uint8_t decryptHandshake(struct CryptoAuth_Wrapper* wrapper,
             #endif
         } else {
             herPermKey = wrapper->herPerminentPubKey;
-            if (memcmp(header->handshake.publicKey, herPermKey, 32)) {
+            if (Bits_memcmp(header->handshake.publicKey, herPermKey, 32)) {
                 Log_debug(wrapper->context->logger, "Packet contains different perminent key.\n");
                 return Error_AUTHENTICATION;
             }
@@ -755,7 +754,7 @@ static uint8_t decryptHandshake(struct CryptoAuth_Wrapper* wrapper,
             Log_debug(wrapper->context->logger,
                        "Received a packet of unknown type! nonce=%u\n", nonce);
         }
-        if (memcmp(header->handshake.publicKey, wrapper->herPerminentPubKey, 32)) {
+        if (Bits_memcmp(header->handshake.publicKey, wrapper->herPerminentPubKey, 32)) {
             Log_debug(wrapper->context->logger, "Packet contains different perminent key.\n");
             return Error_AUTHENTICATION;
         }
@@ -789,7 +788,7 @@ static uint8_t decryptHandshake(struct CryptoAuth_Wrapper* wrapper,
     // Decrypt her temp public key and the message.
     if (decryptRndNonce(header->handshake.nonce, message, sharedSecret) != 0) {
         // just in case
-        memset(header, 0, Headers_CryptoAuth_SIZE);
+        Bits_memset(header, 0, Headers_CryptoAuth_SIZE);
         Log_debug(wrapper->context->logger,
                   "Dropped message because authenticated decryption failed.\n");
         return Error_AUTHENTICATION;
@@ -830,7 +829,7 @@ static uint8_t decryptHandshake(struct CryptoAuth_Wrapper* wrapper,
         Log_debug(wrapper->context->logger, "There is a buffered message.\n");
     }
 
-    memset(&wrapper->replayProtector, 0, sizeof(struct ReplayProtector));
+    Bits_memset(&wrapper->replayProtector, 0, sizeof(struct ReplayProtector));
 
     setRequiredPadding(wrapper);
     return callReceivedMessage(wrapper, message);
@@ -938,7 +937,7 @@ int32_t CryptoAuth_addUser(String* password,
     struct CryptoAuth_Auth a;
     hashPassword_sha256(&a, password);
     for (uint32_t i = 0; i < context->passwordCount; i++) {
-        if (!memcmp(a.secret, context->passwords[i].secret, 32)) {
+        if (!Bits_memcmp(a.secret, context->passwords[i].secret, 32)) {
             return CryptoAuth_addUser_DUPLICATE;
         }
     }
@@ -1029,7 +1028,7 @@ void CryptoAuth_reset(struct Interface* interface)
     struct CryptoAuth_Wrapper* wrapper = interface->senderContext;
     wrapper->nextNonce = 0;
     wrapper->isInitiator = false;
-    memset(&wrapper->replayProtector, 0, sizeof(struct ReplayProtector));
+    Bits_memset(&wrapper->replayProtector, 0, sizeof(struct ReplayProtector));
 }
 
 int CryptoAuth_getState(struct Interface* interface)

+ 5 - 1
crypto/test/CryptoAuth_test.c

@@ -12,12 +12,16 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strcmp
+#define string_strncmp
+#define string_strlen
 #include "crypto/Random.h"
 #include "crypto/CryptoAuth.h"
 #include "crypto/test/Exports.h"
 #include "io/FileWriter.h"
 #include "benc/Object.h"
 #include "memory/MallocAllocator.h"
+#include "util/platform/libc/string.h"
 #include "util/events/EventBase.h"
 #include "util/Assert.h"
 #include "util/Bits.h"
@@ -50,7 +54,7 @@ static struct Message msg;
 static uint8_t* textBuff;
 #define ALIGNED_LEN(x) (strlen(x) + 4 - (strlen(x) % 4))
 #define MK_MSG(x) \
-    memset(textBuff, 0, BUFFER_SIZE);                                           \
+    Bits_memset(textBuff, 0, BUFFER_SIZE);                                      \
     Bits_memcpy(&textBuff[BUFFER_SIZE - ALIGNED_LEN(x)], x, strlen(x));         \
     msg.length = strlen(x);                                                     \
     msg.bytes = textBuff + BUFFER_SIZE - ALIGNED_LEN(x);                        \

+ 14 - 11
crypto/test/CryptoAuth_unit_test.c

@@ -12,12 +12,15 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strcpy
+#define string_strlen
 #include "crypto/CryptoAuth_pvt.h"
 #include "crypto/test/Exports.h"
 #include "io/FileWriter.h"
 #include "memory/BufferAllocator.h"
 #include "memory/MallocAllocator.h"
 #include "memory/Allocator.h"
+#include "util/platform/libc/string.h"
 #include "util/events/EventBase.h"
 #include "util/Assert.h"
 #include "util/Bits.h"
@@ -42,13 +45,13 @@ static uint8_t* hello = (uint8_t*) "Hello World";
 void encryptRndNonceTest()
 {
     uint8_t buff[44];
-    memset(buff, 0, 44);
+    Bits_memset(buff, 0, 44);
 
     uint8_t nonce[24];
-    memset(nonce, 0, 24);
+    Bits_memset(nonce, 0, 24);
 
     uint8_t secret[32];
-    memset(secret, 0, 32);
+    Bits_memset(secret, 0, 32);
 
     struct Message m = { .bytes=&buff[32], .length=12, .padding=32};
     strcpy((char*) m.bytes, "hello world");
@@ -60,10 +63,10 @@ void encryptRndNonceTest()
     Hex_encode(output, 57, m.bytes, m.length);
 
     //printf("\n%s\n%s\n", (char*) expected, (char*) output);
-    Assert_always(!memcmp(expected, output, 56));
+    Assert_always(!Bits_memcmp(expected, output, 56));
 
     Assert_always(!Exports_decryptRndNonce(nonce, &m, secret));
-    Assert_always(m.length == 12 && !memcmp(m.bytes, "hello world", m.length));
+    Assert_always(m.length == 12 && !Bits_memcmp(m.bytes, "hello world", m.length));
 }
 
 void createNew()
@@ -74,7 +77,7 @@ void createNew()
     /*for (int i = 0; i < 32; i++) {
         printf("%.2x", ca->publicKey[i]);
     }*/
-    Assert_always(memcmp(ca->publicKey, publicKey, 32) == 0);
+    Assert_always(Bits_memcmp(ca->publicKey, publicKey, 32) == 0);
 }
 
 static uint8_t receiveMessage(struct Message* message, struct Interface* iface)
@@ -92,7 +95,7 @@ static uint8_t sendMessage(struct Message* message, struct Interface* iface)
 // This needs to be determinent.
 void Random_bytes(struct Random* rand, uint8_t* buffer, uint64_t size)
 {
-    memset(buffer, 0xFF, size);
+    Bits_memset(buffer, 0xFF, size);
 }
 
 struct CryptoAuth_Wrapper* setUp(uint8_t* myPrivateKey,
@@ -155,7 +158,7 @@ void testHello(uint8_t* password, uint8_t* expectedOutput)
     uint8_t actual[265];
     Assert_always(Hex_encode(actual, 265, outMessage->bytes, outMessage->length) > 0);
     //printf("%s", actual);
-    if (memcmp(actual, expectedOutput, 264)) {
+    if (Bits_memcmp(actual, expectedOutput, 264)) {
         printf("Test failed.\n"
                "Expected %s\n"
                "     Got %s\n", expectedOutput, actual);
@@ -214,7 +217,7 @@ void receiveHelloWithNoAuth()
 
     Assert_always(finalOut);
     Assert_always(finalOut->length == 12);
-    Assert_always(memcmp(hello, finalOut->bytes, 12) == 0);
+    Assert_always(Bits_memcmp(hello, finalOut->bytes, 12) == 0);
     //printf("bytes=%s  length=%u\n", finalOut->bytes, finalOut->length);
 }
 
@@ -255,7 +258,7 @@ void repeatHello()
     Exports_encryptHandshake(&msg2, &wrapper);
 
     // Check the nonce
-    Assert_always(!memcmp(msg2.bytes, "\0\0\0\1", 4));
+    Assert_always(!Bits_memcmp(msg2.bytes, "\0\0\0\1", 4));
 
     ca = CryptoAuth_new(allocator, privateKey, eventBase, logger, NULL);
     struct Message* finalOut = NULL;
@@ -272,7 +275,7 @@ void repeatHello()
 
     Assert_always(finalOut);
     Assert_always(finalOut->length == 12);
-    Assert_always(memcmp(hello, finalOut->bytes, 12) == 0);
+    Assert_always(Bits_memcmp(hello, finalOut->bytes, 12) == 0);
     //printf("bytes=%s  length=%u\n", finalOut->bytes, finalOut->length);
 }
 

+ 1 - 1
dht/AddressMapper.c

@@ -18,7 +18,7 @@
 #include "AddressMapper.h"
 
 #include <stdint.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <stdlib.h>
 
 /* if set, address mapper linked list entries are validated before use */

+ 1 - 1
dht/DHTModuleRegistry.c

@@ -23,7 +23,7 @@
 #include "benc/serialization/standard/StandardBencSerializer.h"
 
 #include "util/Assert.h"
-#include <string.h>
+#include "util/platform/libc/string.h"
 
 #define DEBUG2(x, y)
 /* #define DEBUG2(x, y) fprintf(stderr, x, y); fflush(stderr) */

+ 1 - 1
dht/ReplyModule.c

@@ -12,7 +12,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <string.h>
+#include "util/platform/libc/string.h"
 
 #include "dht/CJDHTConstants.h"
 #include "dht/DHTMessage.h"

+ 1 - 1
dht/SerializationModule.c

@@ -27,7 +27,7 @@
 #include "util/Bits.h"
 #include "util/log/Log.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 
 #define SERIALIZER StandardBencSerializer_get()
 

+ 5 - 5
dht/dhtcore/DistanceNodeCollector.h

@@ -19,7 +19,7 @@
 #include "dht/dhtcore/NodeCollector.h"
 #include "util/Bits.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <stdbool.h>
 
 /**
@@ -40,9 +40,9 @@ static inline void DistanceNodeCollector_addNode(struct NodeHeader* header,
     // This is a hack because we don't really care about
     // beyond the first 4 bytes unless it's a match.
     if (nodeDistance == 0
-        && memcmp(body->address.ip6.bytes,
-                  collector->targetAddress,
-                  Address_SEARCH_TARGET_SIZE) != 0)
+        && Bits_memcmp(body->address.ip6.bytes,
+                       collector->targetAddress,
+                       Address_SEARCH_TARGET_SIZE) != 0)
     {
         nodeDistance++;
     }
@@ -80,7 +80,7 @@ static inline void DistanceNodeCollector_addNode(struct NodeHeader* header,
 
         if (i > 0) {
             if (i > 1) {
-                memmove(nodes, &nodes[1], (i - 1) * sizeof(struct NodeCollector_Element));
+                Bits_memmove(nodes, &nodes[1], (i - 1) * sizeof(struct NodeCollector_Element));
             }
             nodes[i - 1].node = header;
             nodes[i - 1].body = body;

+ 1 - 1
dht/dhtcore/Janitor.c

@@ -31,7 +31,7 @@
 #include "util/Timeout.h"
 #include "util/Time.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <stdint.h>
 #include <stdbool.h>
 

+ 7 - 6
dht/dhtcore/LinkStateNodeCollector.h

@@ -22,7 +22,6 @@
 #include "util/log/Log.h"
 #include "memory/Allocator.h"
 
-#include <string.h>
 #include <stdbool.h>
 
 /**
@@ -44,9 +43,9 @@ static inline void LinkStateNodeCollector_addNode(struct NodeHeader* header,
     // This is a hack because we don't really care about
     // beyond the first 4 bytes unless it's a match.
     if (nodeDistance == 0
-        && memcmp(body->address.ip6.bytes,
-                  collector->targetAddress,
-                  Address_SEARCH_TARGET_SIZE) != 0)
+        && Bits_memcmp(body->address.ip6.bytes,
+                       collector->targetAddress,
+                       Address_SEARCH_TARGET_SIZE) != 0)
     {
         Log_debug(collector->logger, "Increasing distance because addr is not exact match.\n");
         nodeDistance++;
@@ -78,7 +77,9 @@ static inline void LinkStateNodeCollector_addNode(struct NodeHeader* header,
                 }
                 if (i > 0
                     && nodes[i].body
-                    && memcmp(body->address.ip6.bytes, nodes[i].body->address.ip6.bytes, 16) == 0)
+                    && Bits_memcmp(body->address.ip6.bytes,
+                                   nodes[i].body->address.ip6.bytes,
+                                   16) == 0)
                 {
                     match = i + 1;
                 }
@@ -91,7 +92,7 @@ static inline void LinkStateNodeCollector_addNode(struct NodeHeader* header,
             if (match > 0) {
                 i = match;
             } else if (i > 1) {
-                memmove(nodes, &nodes[1], (i - 1) * sizeof(struct NodeCollector_Element));
+                Bits_memmove(nodes, &nodes[1], (i - 1) * sizeof(struct NodeCollector_Element));
             }
             nodes[i - 1].node = header;
             nodes[i - 1].body = body;

+ 8 - 6
dht/dhtcore/NodeCollector.h

@@ -21,7 +21,7 @@
 #include "util/log/Log.h"
 #include "memory/Allocator.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <stdbool.h>
 
 struct NodeCollector_Element
@@ -118,9 +118,9 @@ static inline void NodeCollector_addNode(struct NodeHeader* header,
     // This is a hack because we don't really care about
     // beyond the first 4 bytes unless it's a match.
     if (nodeDistance == 0
-        && memcmp(body->address.ip6.bytes,
-                  collector->targetAddress,
-                  Address_SEARCH_TARGET_SIZE) != 0)
+        && Bits_memcmp(body->address.ip6.bytes,
+                       collector->targetAddress,
+                       Address_SEARCH_TARGET_SIZE) != 0)
     {
         Log_debug(collector->logger, "Increasing distance because addr is not exact match.\n");
         nodeDistance++;
@@ -153,7 +153,9 @@ static inline void NodeCollector_addNode(struct NodeHeader* header,
                 }
                 if (i > 0
                     && nodes[i].body
-                    && memcmp(body->address.ip6.bytes, nodes[i].body->address.ip6.bytes, 16) == 0)
+                    && Bits_memcmp(body->address.ip6.bytes,
+                                   nodes[i].body->address.ip6.bytes,
+                                   16) == 0)
                 {
                     match = i + 1;
                 }
@@ -166,7 +168,7 @@ static inline void NodeCollector_addNode(struct NodeHeader* header,
             if (match > 0) {
                 i = match;
             } else if (i > 1) {
-                memmove(nodes, &nodes[1], (i - 1) * sizeof(struct NodeCollector_Element));
+                Bits_memmove(nodes, &nodes[1], (i - 1) * sizeof(struct NodeCollector_Element));
             }
             nodes[i - 1].node = header;
             nodes[i - 1].body = body;

+ 8 - 4
dht/dhtcore/NodeStore.c

@@ -12,6 +12,9 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strcpy
+#define string_strlen
+
 #include "admin/Admin.h"
 #include "benc/Int.h"
 #include "benc/List.h"
@@ -27,6 +30,7 @@
 #include "dht/dhtcore/NodeStore_pvt.h"
 #include "dht/dhtcore/NodeCollector.h"
 #include "dht/dhtcore/NodeList.h"
+#include "util/platform/libc/string.h"
 #include "util/Assert.h"
 #include "util/Bits.h"
 #include "util/log/Log.h"
@@ -83,7 +87,7 @@ struct Node* NodeStore_getNode(struct NodeStore* store, struct Address* addr)
     uint32_t bestReach = 0;
     for (int32_t i = 0; i < (int32_t) store->size; i++) {
         if (pfx == store->headers[i].addressPrefix
-            && memcmp(addr->key, store->nodes[i].address.key, Address_KEY_SIZE) == 0
+            && Bits_memcmp(addr->key, store->nodes[i].address.key, Address_KEY_SIZE) == 0
             && store->headers[i].reach >= bestReach)
         {
             bestIndex = i;
@@ -147,7 +151,7 @@ struct Node* NodeStore_addNode(struct NodeStore* store,
     }
 
     Address_getPrefix(addr);
-    if (memcmp(addr->ip6.bytes, store->thisNodeAddress, 16) == 0) {
+    if (Bits_memcmp(addr->ip6.bytes, store->thisNodeAddress, 16) == 0) {
         printf("got introduced to ourselves\n");
         return NULL;
     }
@@ -217,7 +221,7 @@ struct Node* NodeStore_addNode(struct NodeStore* store,
                 else if (store->headers[i].addressPrefix == pfx) {
                     uint8_t realAddr[16];
                     AddressCalc_addressForPublicKey(realAddr, addr->key);
-                    Assert_true(!memcmp(realAddr, addr->ip6.bytes, 16));
+                    Assert_true(!Bits_memcmp(realAddr, addr->ip6.bytes, 16));
                 }
             #endif
         }
@@ -328,7 +332,7 @@ struct NodeList* NodeStore_getNodesByAddr(struct Address* address,
     uint32_t outIndex = 0;
     for (uint32_t i = 0; i < max; i++) {
         if (collector->nodes[i].node != NULL
-            && !memcmp(collector->nodes[i].body->address.ip6.bytes, address->ip6.bytes, 16))
+            && !Bits_memcmp(collector->nodes[i].body->address.ip6.bytes, address->ip6.bytes, 16))
         {
             out->nodes[outIndex] = collector->nodes[i].body;
             outIndex++;

+ 7 - 5
dht/dhtcore/RouterModule.c

@@ -12,6 +12,8 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strlen
+
 #include "benc/Int.h"
 #include "benc/Object.h"
 #include "dht/Address.h"
@@ -37,8 +39,8 @@
 #include "util/Time.h"
 #include "util/Timeout.h"
 #include "util/version/Version.h"
+#include "util/platform/libc/string.h"
 
-#include <string.h>
 #include <stdint.h>
 #include <event2/event.h>
 #include <stdbool.h>
@@ -301,7 +303,7 @@ static void pingNode(Dict* args, void* vrouter, String* txid)
             err = "parsing address failed";
         } else {
             n = RouterModule_lookup(addr.ip6.bytes, router);
-            if (n && memcmp(addr.ip6.bytes, n->address.ip6.bytes, 16)) {
+            if (n && Bits_memcmp(addr.ip6.bytes, n->address.ip6.bytes, 16)) {
                 n = NULL;
             }
         }
@@ -417,7 +419,7 @@ static inline void sendRequest(struct Address* address,
                                struct DHTModuleRegistry* registry)
 {
     struct DHTMessage message;
-    memset(&message, 0, sizeof(struct DHTMessage));
+    Bits_memset(&message, 0, sizeof(struct DHTMessage));
 
     char buffer[4096];
     struct Allocator* allocator = BufferAllocator_new(buffer, 4096);
@@ -510,7 +512,7 @@ static void searchStep(struct SearchCallbackContext* scc)
 
     // Get the node from the nodestore because there might be a much better path to the same node.
     struct Node* n = NodeStore_getBest(nextSearchNode->address, scc->routerModule->nodeStore);
-    if (n && !memcmp(n->address.ip6.bytes, nextSearchNode->address->ip6.bytes, 16)) {
+    if (n && !Bits_memcmp(n->address.ip6.bytes, nextSearchNode->address->ip6.bytes, 16)) {
         uint64_t nlabel = n->address.path;
         uint64_t nsn = nextSearchNode->address->path;
         if (nlabel < nsn) {
@@ -624,7 +626,7 @@ static inline bool isDuplicateEntry(String* nodes, uint32_t index)
         if (i == index) {
             continue;
         }
-        if (memcmp(&nodes->bytes[index], &nodes->bytes[i], Address_KEY_SIZE) == 0) {
+        if (Bits_memcmp(&nodes->bytes[index], &nodes->bytes[i], Address_KEY_SIZE) == 0) {
             return true;
         }
     }

+ 1 - 1
dht/dhtcore/SearchStore.c

@@ -12,7 +12,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <string.h>
+#include "util/platform/libc/string.h"
 
 #include "dht/Address.h"
 #include "dht/dhtcore/SearchStore.h"

+ 2 - 2
dht/test/address_mapper_lru_test.c

@@ -14,9 +14,9 @@
  */
 #include "memory/MallocAllocator.h"
 #include "dht/AddressMapper.h"
+#include "util/Bits.h"
 
 #include <stdio.h>
-#include <string.h>
 #include <time.h>
 
 /* collection of data required to run tests */
@@ -463,7 +463,7 @@ int main(int argc, char** argv)
         for (int rpt = 0; rpt < NUM_REPEAT; rpt++) {
             int testErr;
 
-            memset(&info, 0, sizeof(info));
+            Bits_memset(&info, 0, sizeof(info));
             initAppState(&state);
             testErr = testRunList[testNum](&state, state.map, &info);
             deinitAppState(&state);

+ 1 - 1
exception/Except.c

@@ -17,7 +17,7 @@
 #include "exception/Except.h"
 
 #include <stdarg.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <stdio.h>
 #include <stdlib.h>
 

+ 0 - 126
interface/InterfaceMap.h

@@ -1,126 +0,0 @@
-/* vim: set expandtab ts=4 sw=4: */
-/*
- * You may redistribute this program and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef InterfaceMap_H
-#define InterfaceMap_H
-
-#ifdef WIN32
-    #undef interface
-#endif
-
-struct InterfaceMap_Entry;
-struct InterfaceMap
-{
-    uint32_t* keyPrefixes;
-    uint8_t* keys;
-    struct Interface** interfaces;
-    uint32_t* lastMessageTimes;
-
-    uint32_t count;
-    uint32_t capacity;
-
-    size_t keySize;
-
-    struct Allocator* allocator;
-};
-
-static inline struct InterfaceMap* InterfaceMap_new(size_t keySize,
-                                                    struct Allocator* allocator)
-{
-    return allocator->clone(sizeof(struct InterfaceMap), allocator, &(struct InterfaceMap) {
-        .keySize = keySize,
-        .allocator = allocator
-    });
-}
-
-/**
- * This is a very hot loop,
- * a large amount of code relies on this being fast so it is a good target for optimization.
- */
-static inline int InterfaceMap_indexOf(uint8_t* key, struct InterfaceMap* map)
-{
-    uint32_t keyPrefix;
-    Bits_memcpyConst(&keyPrefix, key, 4);
-    for (uint32_t i = 0; i < map->count; i++) {
-        if (map->keyPrefixes[i] == keyPrefix
-            && memcmp(key, &map->keys[map->keySize * i], map->keySize) == 0)
-        {
-            return i;
-        }
-    }
-    return -1;
-}
-
-/**
- * @param key the key of the entry to remove.
- * @param map the map to remove from.
- * @return 0 if the entry is removed, -1 if it could not be found.
- */
-static inline int InterfaceMap_remove(int index, struct InterfaceMap* map)
-{
-    if (index >= 0 && index < (int) map->count) {
-        map->count--;
-        if (index < (int) map->count) {
-            map->keyPrefixes[index] = map->keyPrefixes[map->count];
-            Bits_memcpy(&map->keys[map->keySize * index],
-                        &map->keys[map->keySize * map->count],
-                        map->keySize);
-            map->interfaces[index] = map->interfaces[map->count];
-            map->lastMessageTimes[index] = map->lastMessageTimes[map->count];
-        }
-        return 0;
-    }
-    return -1;
-}
-
-static inline int InterfaceMap_put(uint8_t* key,
-                                   struct Interface* interface,
-                                   uint32_t timeOfLastMessage,
-                                   struct InterfaceMap* map)
-{
-    if (map->count == map->capacity) {
-        map->keyPrefixes =
-            map->allocator->realloc(map->keyPrefixes,
-                                    sizeof(uint32_t) * (map->count + 10),
-                                    map->allocator);
-        map->keys =
-            map->allocator->realloc(map->keys,
-                                    map->keySize * (map->count + 10),
-                                    map->allocator);
-        map->interfaces =
-            map->allocator->realloc(map->interfaces,
-                                    sizeof(char*) * (map->count + 10),
-                                    map->allocator);
-        map->lastMessageTimes =
-            map->allocator->realloc(map->lastMessageTimes,
-                                    sizeof(uint32_t) * (map->count + 10),
-                                    map->allocator);
-        map->capacity += 10;
-    }
-
-    int i = InterfaceMap_indexOf(key, map);
-    if (i < 0) {
-        i = map->count;
-        map->count++;
-    }
-
-    Bits_memcpyConst(&map->keyPrefixes[i], key, 4);
-    Bits_memcpy(&map->keys[map->keySize * i], key, map->keySize);
-    map->interfaces[i] = interface;
-    map->lastMessageTimes[i] = timeOfLastMessage;
-
-    return i;
-}
-
-#endif

+ 1 - 1
interface/TUNConfigurator_FreeBSD.c

@@ -30,7 +30,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <net/if.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <netdb.h>
 #include <net/if_var.h>
 #include <net/if_tun.h>

+ 1 - 1
interface/TUNConfigurator_Illumos.c

@@ -20,7 +20,7 @@
 #include <stdio.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <stdlib.h>

+ 5 - 4
interface/TUNConfigurator_Linux.c

@@ -16,8 +16,9 @@
 #include "interface/TUNConfigurator.h"
 #include "util/AddrTools.h"
 #include "util/Errno.h"
-
-#include <string.h>
+#define string_strncpy
+#define string_strlen
+#include "util/platform/libc/string.h"
 #include <stdio.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
@@ -116,7 +117,7 @@ static int socketForIfName(const char* interfaceName,
                      "socket() failed: [%s]", Errno_getString());
     }
 
-    memset(ifRequestOut, 0, sizeof(struct ifreq));
+    Bits_memset(ifRequestOut, 0, sizeof(struct ifreq));
     strncpy(ifRequestOut->ifr_name, interfaceName, IFNAMSIZ);
 
     if (ioctl(s, SIOCGIFINDEX, ifRequestOut) < 0) {
@@ -166,7 +167,7 @@ void TUNConfigurator_setIpAddress(const char* interfaceName,
     int s = socketForIfName(interfaceName, eh, &ifRequest);
 
     struct in6_ifreq ifr6;
-    memset(&ifr6, 0, sizeof(struct in6_ifreq));
+    Bits_memset(&ifr6, 0, sizeof(struct in6_ifreq));
     // checkInterfaceUp() clobbers the ifindex.
     ifr6.ifr6_ifindex = ifRequest.ifr_ifindex;
 

+ 1 - 1
interface/TUNConfigurator_OSX.c

@@ -26,7 +26,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <net/if.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <netdb.h>
 #include <net/if_var.h>
 #include <netinet/in_var.h>

+ 1 - 1
interface/TUNConfigurator_OpenBSD.c

@@ -30,7 +30,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <net/if.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <netdb.h>
 #include <net/if_tun.h>
 #include <netinet/in.h>

+ 1 - 1
interface/TUNInterface.c

@@ -18,7 +18,7 @@
 #include "util/Endian.h"
 #include "util/Errno.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <event2/event.h>
 #include <net/if.h>
 #include <fcntl.h>

+ 1 - 1
interface/TUNInterface_W32.c

@@ -17,7 +17,7 @@
 #include "benc/String.h"
 #include "util/Endian.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <event2/event.h>
 
 #include <winsock2.h>

+ 0 - 1
interface/UDPInterface_admin.c

@@ -22,7 +22,6 @@
 #include "crypto/Key.h"
 
 #include <event2/event.h>
-#include <string.h>
 
 struct Context
 {

+ 4 - 1
interface/test/UDPInterface_test.c

@@ -12,6 +12,8 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strcmp
+#define string_strlen
 #include "admin/testframework/AdminTestFramework.h"
 #include "admin/Admin.h"
 #include "admin/AdminClient.h"
@@ -24,10 +26,11 @@
 #include "net/InterfaceController.h"
 #include "io/FileWriter.h"
 #include "io/Writer.h"
+#include "util/Assert.h"
 #include "util/log/Log.h"
+#include "util/platform/libc/string.h"
 
 #include <event2/event.h>
-#include "util/Assert.h"
 
 static int insertEndpointCalls = 0;
 static int insertEndpoint(uint8_t key[InterfaceController_KEY_SIZE],

+ 2 - 2
io/test/FileReader_test.c

@@ -18,8 +18,8 @@
 #include "memory/Allocator.h"
 #include "memory/MallocAllocator.h"
 #include "util/Assert.h"
+#include "util/Bits.h"
 
-#include <string.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdbool.h>
@@ -52,7 +52,7 @@ int main()
     uint8_t* ptr2 = buffer2;
 
     #define SKIP(x) ptr1 += x
-    #define CMP(x) Assert_always(!memcmp(ptr1, ptr2, x)); ptr1 += x; ptr2 += x
+    #define CMP(x) Assert_always(!Bits_memcmp(ptr1, ptr2, x)); ptr1 += x; ptr2 += x
 
     CMP(128);
     SKIP(128);

+ 3 - 3
memory/MallocAllocator.c

@@ -12,7 +12,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <stdint.h>
 #include <stdio.h>
 
@@ -145,7 +145,7 @@ static void freeAllocator(const struct Allocator* allocator)
         *(context->spaceAvailable) += loc->size;
         struct Allocation* nextLoc = loc->next;
         #ifdef Log_DEBUG
-            memset(loc, 0xff, loc->size);
+            Bits_memset(loc, 0xff, loc->size);
         #endif
         free(loc);
         loc = nextLoc;
@@ -162,7 +162,7 @@ static void* allocatorMalloc(size_t length, const struct Allocator* allocator)
 static void* allocatorCalloc(size_t length, size_t count, const struct Allocator* allocator)
 {
     void* pointer = allocator->malloc(length * count, allocator);
-    memset(pointer, 0, length * count);
+    Bits_memset(pointer, 0, length * count);
     return pointer;
 }
 

+ 1 - 1
memory/test/MallocAllocator_test.c

@@ -13,7 +13,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include "util/Assert.h"
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <stdint.h>
 #include <stdio.h>
 

+ 44 - 45
net/DefaultInterfaceController.c

@@ -14,7 +14,6 @@
  */
 #include "crypto/CryptoAuth_pvt.h"
 #include "net/DefaultInterfaceController.h"
-#include "interface/InterfaceMap.h"
 #include "memory/Allocator.h"
 #include "net/SwitchPinger.h"
 #include "util/Bits.h"
@@ -25,6 +24,7 @@
 
 #include <stddef.h> // offsetof
 
+
 #ifndef CJDNS_MAX_PEERS
     #error CJDNS_MAX_PEERS needs to be defined.
 #endif
@@ -39,6 +39,10 @@
 #define TIMEOUT_MILLISECONDS 2000
 
 /*--------------------Structs--------------------*/
+struct MapKey {
+    uint8_t bytes[InterfaceController_KEY_SIZE];
+};
+Assert_compileTime(sizeof(struct MapKey) == InterfaceController_KEY_SIZE);
 
 struct Endpoint
 {
@@ -60,7 +64,7 @@ struct Endpoint
     struct Interface* external;
 
     /** The lookup key for this endpoint (ip/mac address) */
-    uint8_t key[InterfaceController_KEY_SIZE];
+    struct MapKey key;
 
     /** The label for this endpoint, needed to ping the endpoint. */
     uint64_t switchLabel;
@@ -91,15 +95,19 @@ struct Endpoint
     uint32_t timeOfLastMessage;
 };
 
+
+#define Map_NAME OfEndpointsByKey
+#define Map_KEY_TYPE struct MapKey
+#define Map_VALUE_TYPE struct Endpoint
+#include "util/Map.h"
+
 struct Context
 {
     /** Public functions and fields for this ifcontroller. */
     struct InterfaceController pub;
 
     /** Used to get an endpoint by it's lookup key, endpoint.internal is entered into the map. */
-    struct InterfaceMap* const imap;
-
-    struct Endpoint endpoints[CJDNS_MAX_PEERS];
+    struct Map_OfEndpointsByKey endpointMap;
 
     struct Allocator* const allocator;
 
@@ -154,7 +162,7 @@ static void onPingResponse(enum SwitchPinger_Result result,
     struct Endpoint* ep = onResponseContext;
     struct Context* ic = interfaceControllerForEndpoint(ep);
     struct Address addr;
-    memset(&addr, 0, sizeof(struct Address));
+    Bits_memset(&addr, 0, sizeof(struct Address));
     Bits_memcpyConst(addr.key, CryptoAuth_getHerPublicKey(ep->cryptoAuthIf), 32);
     addr.path = ep->switchLabel;
     Log_debug(ic->logger, "got switch pong from node with version [%d]", version);
@@ -180,11 +188,13 @@ static void pingCallback(void* vic)
     ic->pingCount++;
 
     // scan for endpoints have not sent anything recently.
-    for (int i = 0; i < CJDNS_MAX_PEERS; i++) {
-        struct Endpoint* ep = &ic->endpoints[i];
-        if (ep->external != NULL && now > ep->timeOfLastMessage + ic->pingAfterMilliseconds) {
-            uint8_t path[20];
-            AddrTools_printPath(path, ep->switchLabel);
+    for (uint32_t i = 0; i < ic->endpointMap.count; i++) {
+        struct Endpoint* ep = &ic->endpointMap.values[i];
+        if (now > ep->timeOfLastMessage + ic->pingAfterMilliseconds) {
+            #ifdef Log_DEBUG
+                uint8_t path[20];
+                AddrTools_printPath(path, ep->switchLabel);
+            #endif
             if (now > ep->timeOfLastMessage + ic->unresponsiveAfterMilliseconds) {
                 // Lets skip 87% of pings when they're really down.
                 if (ic->pingCount % 8) {
@@ -218,18 +228,10 @@ static void moveEndpointIfNeeded(struct Endpoint* ep, struct Context* ic)
     Log_debug(ic->logger, "Checking for old sessions to merge with.");
 
     uint8_t* key = CryptoAuth_getHerPublicKey(ep->cryptoAuthIf);
-    for (int i = 0; i < CJDNS_MAX_PEERS; i++) {
-        struct Endpoint* thisEp = &ic->endpoints[i];
-        if (thisEp >= ep) {
-            Assert_true(i == 0 || thisEp == ep);
-            break;
-        }
-        if (thisEp->external == NULL) {
-            // Removed endpoint.
-            continue;
-        }
+    for (uint32_t i = 0; i < ic->endpointMap.count; i++) {
+        struct Endpoint* thisEp = &ic->endpointMap.values[i];
         uint8_t* thisKey = CryptoAuth_getHerPublicKey(thisEp->cryptoAuthIf);
-        if (!memcmp(thisKey, key, 32)) {
+        if (!Bits_memcmp(thisKey, key, 32)) {
             Log_info(ic->logger, "Moving endpoint to merge new session with old.");
 
             ep->switchLabel = thisEp->switchLabel;
@@ -255,7 +257,7 @@ static uint8_t receivedAfterCryptoAuth(struct Message* msg, struct Interface* cr
             // prevent some kinds of nasty things which could be done with packet replay.
             // This is checking the message switch header and will drop it unless the label
             // directs it to *this* router.
-            if (msg->length < 8 || memcmp(msg->bytes, "\0\0\0\0\0\0\0\1", 8)) {
+            if (msg->length < 8 || Bits_memcmp(msg->bytes, "\0\0\0\0\0\0\0\1", 8)) {
                 Log_info(ic->logger, "Dropping message because CA is not established.");
                 return Error_NONE;
             }
@@ -309,9 +311,9 @@ static void closeInterface(void* vendpoint)
     struct Endpoint* toClose = (struct Endpoint*) vendpoint;
     struct Context* ic = toClose->internal.senderContext;
 
-    int index = InterfaceMap_indexOf(toClose->key, ic->imap);
+    int index = Map_OfEndpointsByKey_indexForKey(&toClose->key, &ic->endpointMap);
     Assert_true(index >= 0);
-    InterfaceMap_remove(index, ic->imap);
+    Map_OfEndpointsByKey_remove(index, &ic->endpointMap);
 
     // flag the entry as nolonger used.
     toClose->external = NULL;
@@ -326,7 +328,7 @@ static uint8_t sendMessage(struct Message* message, struct Interface* iface)
     struct Endpoint* ep = endpointForInternalInterface(iface);
 
     Message_shift(message, InterfaceController_KEY_SIZE);
-    Bits_memcpyConst(message->bytes, ep->key, InterfaceController_KEY_SIZE);
+    Bits_memcpyConst(message->bytes, &ep->key, InterfaceController_KEY_SIZE);
 
     Assert_true(ep->external);
     return ep->external->sendMessage(message, ep->external);
@@ -335,13 +337,13 @@ static uint8_t sendMessage(struct Message* message, struct Interface* iface)
 static inline struct Endpoint* getEndpoint(uint8_t key[InterfaceController_KEY_SIZE],
                                            struct Context* ic)
 {
-    int index = InterfaceMap_indexOf(key, ic->imap);
+    struct MapKey* k = (struct MapKey*) key;
+    int index = Map_OfEndpointsByKey_indexForKey(k, &ic->endpointMap);
     if (index > -1) {
-        struct Endpoint* ep = endpointForInternalInterface(ic->imap->interfaces[index]);
+        struct Endpoint* ep = &ic->endpointMap.values[index];
         #ifdef Log_DEBUG
             Assert_true(ep->external || !"Entry was not removed from the map but was null.");
-            Assert_true(&ep->internal == ic->imap->interfaces[index]);
-            Assert_true(!memcmp(key, ep->key, InterfaceController_KEY_SIZE));
+            Assert_true(!Bits_memcmp(key, &ep->key, InterfaceController_KEY_SIZE));
         #endif
         return ep;
     }
@@ -387,19 +389,16 @@ static struct Endpoint* insertEndpoint(uint8_t key[InterfaceController_KEY_SIZE]
         return NULL;
     }
 
-    // scan for an unused endpoint slot.
-    struct Endpoint* ep = NULL;
-    for (int i = 0; i < CJDNS_MAX_PEERS; i++) {
-        if (ic->endpoints[i].external == NULL) {
-            Log_debug(ic->logger, "Using connection slot [%d]", i);
-            ep = &ic->endpoints[i];
-            break;
-        }
-    }
-    if (!ep) {
+    if (ic->endpointMap.count >= CJDNS_MAX_PEERS) {
         return NULL;
     }
 
+    int index = Map_OfEndpointsByKey_put(((struct MapKey*)key),
+                                         &(struct Endpoint){.state=0},
+                                         &ic->endpointMap);
+
+    struct Endpoint* ep = &ic->endpointMap.values[index];
+
     // If the other end need not supply a valid password to connect
     // we will set the connection state to HANDSHAKE because we don't
     // want the connection to be trashed after the first invalid packet.
@@ -411,14 +410,12 @@ static struct Endpoint* insertEndpoint(uint8_t key[InterfaceController_KEY_SIZE]
     externalInterface->receiverContext = ic;
     externalInterface->receiveMessage = receiveMessage;
 
-
     struct Allocator* epAllocator =
         externalInterface->allocator->child(externalInterface->allocator);
     epAllocator->onFree(closeInterface, ep, epAllocator);
 
     ep->external = externalInterface;
-    Bits_memcpyConst(ep->key, key, InterfaceController_KEY_SIZE);
-    InterfaceMap_put(key, &ep->internal, 0, ic->imap);
+    Bits_memcpyConst(&ep->key, key, InterfaceController_KEY_SIZE);
 
     Bits_memcpyConst(&ep->internal, (&(struct Interface) {
         .senderContext = ic,
@@ -444,7 +441,7 @@ static struct Endpoint* insertEndpoint(uint8_t key[InterfaceController_KEY_SIZE]
     }), sizeof(struct Interface));
 
     struct Address addr;
-    memset(&addr, 0, sizeof(struct Address));
+    Bits_memset(&addr, 0, sizeof(struct Address));
     if (SwitchCore_addInterface(&ep->switchIf, 0, &addr.path, ic->switchCore)) {
         return NULL;
     }
@@ -548,7 +545,9 @@ struct InterfaceController* DefaultInterfaceController_new(struct CryptoAuth* ca
             .insertEndpoint = insertEndpointPublic,
             .registerInterface = registerInterfacePublic
         },
-        .imap = InterfaceMap_new(InterfaceController_KEY_SIZE, allocator),
+        .endpointMap = {
+            .allocator = allocator
+        },
         .allocator = allocator,
         .ca = ca,
         .switchCore = switchCore,

+ 12 - 13
net/Ducttape.c

@@ -21,7 +21,6 @@
 #include "dht/dhtcore/Node.h"
 #include "dht/dhtcore/RouterModule.h"
 #include "interface/Interface.h"
-#include "interface/InterfaceMap.h"
 #include "interface/SessionManager.h"
 #include "util/log/Log.h"
 #include "memory/Allocator.h"
@@ -68,7 +67,7 @@ static inline uint8_t incomingDHT(struct Message* message,
                                   struct Ducttape_Private* context)
 {
     struct DHTMessage dht;
-    memset(&dht, 0, sizeof(struct DHTMessage));
+    Bits_memset(&dht, 0, sizeof(struct DHTMessage));
 
     // TODO: These copies are not necessary at all.
     const uint32_t length = (message->length < DHTMessage_MAX_SIZE)
@@ -104,7 +103,7 @@ static inline uint8_t sendToRouter(struct Node* node,
     if (context->switchHeader) {
         Bits_memcpyConst(&header, context->switchHeader, Headers_SwitchHeader_SIZE);
     } else {
-        memset(&header, 0, Headers_SwitchHeader_SIZE);
+        Bits_memset(&header, 0, Headers_SwitchHeader_SIZE);
     }
     header.label_be = Endian_hostToBigEndian64(addr->path);
     context->switchHeader = &header;
@@ -204,7 +203,7 @@ static inline uint8_t incomingForMe(struct Message* message,
     Bits_memcpyConst(addr.ip6.bytes, context->session->ip6, 16);
     //AddressCalc_addressForPublicKey(addr.ip6.bytes, herPubKey);
 
-    if (memcmp(addr.ip6.bytes, context->ip6Header->sourceAddr, 16)) {
+    if (Bits_memcmp(addr.ip6.bytes, context->ip6Header->sourceAddr, 16)) {
         #ifdef Log_DEBUG
             uint8_t keyAddr[40];
             Address_printIp(keyAddr, &addr);
@@ -282,7 +281,7 @@ static inline uint8_t incomingForMe(struct Message* message,
         context->ip6Header->payloadLength_be =
             Endian_hostToBigEndian16(
                 Endian_bigEndianToHost16(context->ip6Header->payloadLength_be) - sizeDiff);
-        memmove(message->bytes, context->ip6Header, Headers_IP6Header_SIZE);
+        Bits_memmoveConst(message->bytes, context->ip6Header, Headers_IP6Header_SIZE);
     }
     context->userIf->sendMessage(message, context->userIf);
     return Error_NONE;
@@ -340,7 +339,7 @@ static inline uint8_t sendToSwitch(struct Message* message,
     // This will be false if an incoming connect-to-me packet caused the cryptoAuth to send
     // back a hello packet.
     if (destinationSwitchHeader != switchHeaderLocation) {
-        memmove(message->bytes, destinationSwitchHeader, Headers_SwitchHeader_SIZE);
+        Bits_memmoveConst(message->bytes, destinationSwitchHeader, Headers_SwitchHeader_SIZE);
     }
 
     return context->switchInterface.receiveMessage(message, &context->switchInterface);
@@ -358,7 +357,7 @@ static inline bool validEncryptedIP6(struct Message* message)
 static inline bool isForMe(struct Message* message, struct Ducttape_Private* context)
 {
     struct Headers_IP6Header* header = (struct Headers_IP6Header*) message->bytes;
-    return (memcmp(header->destinationAddr, context->myAddr.ip6.bytes, 16) == 0);
+    return (Bits_memcmp(header->destinationAddr, context->myAddr.ip6.bytes, 16) == 0);
 }
 
 // Called by the TUN device.
@@ -377,7 +376,7 @@ static inline uint8_t incomingFromTun(struct Message* message,
         return Error_INVALID;
     }
 
-    if (memcmp(header->sourceAddr, context->myAddr.ip6.bytes, 16)) {
+    if (Bits_memcmp(header->sourceAddr, context->myAddr.ip6.bytes, 16)) {
         uint8_t expectedSource[40];
         AddrTools_printIp(expectedSource, context->myAddr.ip6.bytes);
         uint8_t packetSource[40];
@@ -387,7 +386,7 @@ static inline uint8_t incomingFromTun(struct Message* message,
                  (char*) packetSource, (char*) expectedSource);
         return Error_INVALID;
     }
-    if (!memcmp(header->destinationAddr, context->myAddr.ip6.bytes, 16)) {
+    if (!Bits_memcmp(header->destinationAddr, context->myAddr.ip6.bytes, 16)) {
         // I'm Gonna Sit Right Down and Write Myself a Letter
         interface->sendMessage(message, interface);
         return Error_NONE;
@@ -398,7 +397,7 @@ static inline uint8_t incomingFromTun(struct Message* message,
     struct Node* bestNext = RouterModule_lookup(header->destinationAddr, context->routerModule);
     context->forwardTo = bestNext;
     if (bestNext) {
-        if (!memcmp(header->destinationAddr, bestNext->address.ip6.bytes, 16)) {
+        if (!Bits_memcmp(header->destinationAddr, bestNext->address.ip6.bytes, 16)) {
             // Direct send, skip the innermost layer of encryption.
             #ifdef Log_DEBUG
                 uint8_t nhAddr[60];
@@ -445,7 +444,7 @@ static uint8_t sendToNode(struct Message* message, struct Interface* iface)
     Message_shift(message, -IpTunnel_PacketInfoHeader_SIZE);
     struct Node* n = RouterModule_lookup(header->nodeIp6Addr, context->routerModule);
     if (n) {
-        if (!memcmp(header->nodeKey, n->address.key, 32)) {
+        if (!Bits_memcmp(header->nodeKey, n->address.key, 32)) {
             // Found the node.
             #ifdef Log_DEBUG
                 uint8_t nhAddr[60];
@@ -498,7 +497,7 @@ static inline int core(struct Message* message, struct Ducttape_Private* context
     if (isForMe(message, context)) {
         Message_shift(message, -Headers_IP6Header_SIZE);
 
-        if (memcmp(context->session->ip6, context->ip6Header->sourceAddr, 16)) {
+        if (Bits_memcmp(context->session->ip6, context->ip6Header->sourceAddr, 16)) {
             // triple encrypted
             // This call goes to incomingForMe()
             struct SessionManager_Session* session =
@@ -545,7 +544,7 @@ static inline int core(struct Message* message, struct Ducttape_Private* context
             struct Address* addr = &nextHop->address;
             uint8_t nhAddr[60];
             Address_print(nhAddr, addr);
-            if (memcmp(context->ip6Header->destinationAddr, addr->ip6.bytes, 16)) {
+            if (Bits_memcmp(context->ip6Header->destinationAddr, addr->ip6.bytes, 16)) {
                 // Potentially forwarding for ourselves.
                 struct Address destination;
                 Bits_memcpyConst(destination.ip6.bytes, context->ip6Header->destinationAddr, 16);

+ 3 - 0
net/test/DefaultInterfaceController_test.c

@@ -12,6 +12,8 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strcmp
+#define string_strlen
 #include "crypto/Random.h"
 #include "crypto/CryptoAuth.h"
 #include "dht/ReplyModule.h"
@@ -23,6 +25,7 @@
 #include "util/log/Log.h"
 #include "util/log/WriterLog.h"
 #include "util/events/EventBase.h"
+#include "util/platform/libc/string.h"
 #include "memory/MallocAllocator.h"
 #include "memory/Allocator.h"
 #include "switch/NumberCompress.h"

+ 1 - 1
scripts/checkfiles.pl

@@ -120,7 +120,7 @@ foreach my $fileName (split("\n", $files))
             error("cjd's editor window is only 100 characters wide");
         }
 
-        if ($fileName =~ /\.h$/) {
+        if ($fileName =~ /\.h$/ && !($fileName =~ /util\/platform\/libc\//)) {
 
             my $n = $name;
             # If the name is CryptoAuth_struct.h, it's ok to make a structure called CryptoAuth

+ 5 - 3
test/CryptoAddress_test.c

@@ -12,14 +12,16 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
+#define string_strcmp
 #include "crypto/AddressCalc.h"
 #include "dht/Address.h"
+#include "util/Bits.h"
 #include "util/Base32.h"
+#include "util/Assert.h"
+#include "util/platform/libc/string.h"
 
 #include "crypto_scalarmult_curve25519.h"
 
-#include "util/Assert.h"
 #include <stdio.h>
 
 // hex: 751d3db85b848deaf221e0ed2b6cc17f587b29057d74cdd4dc0bd18b7157288e
@@ -77,7 +79,7 @@ int main()
            publicKeyBase32Out,
            addressOut);
 
-    Assert_always(0 == memcmp(address.key, publicKey, 32));
+    Assert_always(0 == Bits_memcmp(address.key, publicKey, 32));
     Assert_always(0 == strcmp(publicKeyBase32, (char*) publicKeyBase32Out));
     Assert_always(0 == strcmp(ipv6, (char*) addressOut));
 }

+ 3 - 0
test/cjdroute_injection_test.c

@@ -12,9 +12,12 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strncpy
+#define string_strlen
 #include "memory/MallocAllocator.h"
 #include "memory/Allocator.h"
 #include "net/Ducttape.h"
+#include "util/platform/libc/string.h"
 
 #include "test/TestFramework.h"
 

+ 3 - 0
test/cjdroute_routerPing_test.c

@@ -12,11 +12,14 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strncpy
+#define string_strlen
 #include "memory/MallocAllocator.h"
 #include "memory/Allocator.h"
 #include "net/Ducttape_pvt.h"
 #include "util/Base32.h"
 #include "util/Checksum.h"
+#include "util/platform/libc/string.h"
 
 #include "test/TestFramework.h"
 

+ 3 - 0
tunnel/CMakeLists.txt

@@ -18,3 +18,6 @@ add_library(cjdns-tunnel-iptunnel
 target_link_libraries(cjdns-tunnel-iptunnel
     cjdbenc
 )
+
+enable_testing()
+add_subdirectory(test)

+ 15 - 19
tunnel/IpTunnel.c

@@ -25,6 +25,7 @@
 #include "memory/Allocator.h"
 #include "tunnel/IpTunnel.h"
 #include "crypto/AddressCalc.h"
+#include "util/platform/libc/strlen.h"
 #include "util/Checksum.h"
 #include "util/AddrTools.h"
 #include "util/events/EventBase.h"
@@ -33,16 +34,16 @@
 #include "wire/Headers.h"
 
 #include <stddef.h>
-#include <string.h>
 
-static char IpTunnel_IDENTITY;
+#define Identity_TYPE struct IpTunnel_pvt
+#include "util/Identity.h"
 
 struct IpTunnel_pvt
 {
     struct IpTunnel pub;
 
     /** For verifying the integrity of the structure, must match IpTunnel_IDENTITY. */
-    char* identity;
+    Identity
 
     struct Allocator* allocator;
     struct Log* logger;
@@ -103,7 +104,7 @@ static struct IpTunnel_Connection* connectionByPubKey(uint8_t pubKey[32],
                                                       struct IpTunnel_pvt* context)
 {
     for (int i = 0; i < (int)context->pub.connectionList.count; i++) {
-        if (!memcmp(pubKey, context->pub.connectionList.connections[i].header.nodeKey, 32)) {
+        if (!Bits_memcmp(pubKey, context->pub.connectionList.connections[i].header.nodeKey, 32)) {
             return &context->pub.connectionList.connections[i];
         }
     }
@@ -124,8 +125,7 @@ int IpTunnel_allowConnection(uint8_t publicKeyOfAuthorizedNode[32],
                              uint8_t ip4Address[4],
                              struct IpTunnel* tunnel)
 {
-    struct IpTunnel_pvt* context = (struct IpTunnel_pvt*) tunnel;
-    Assert_true(context->identity == &IpTunnel_IDENTITY);
+    struct IpTunnel_pvt* context = Identity_check(tunnel);
 
     struct IpTunnel_Connection* conn = newConnection(false, context);
     Bits_memcpyConst(conn->header.nodeKey, publicKeyOfAuthorizedNode, 32);
@@ -228,8 +228,7 @@ static uint8_t requestAddresses(struct IpTunnel_Connection* conn,
  */
 int IpTunnel_connectTo(uint8_t publicKeyOfNodeToConnectTo[32], struct IpTunnel* tunnel)
 {
-    struct IpTunnel_pvt* context = (struct IpTunnel_pvt*) tunnel;
-    Assert_true(context->identity == &IpTunnel_IDENTITY);
+    struct IpTunnel_pvt* context = Identity_check(tunnel);
 
     struct IpTunnel_Connection* conn = newConnection(true, context);
     Bits_memcpyConst(conn->header.nodeKey, publicKeyOfNodeToConnectTo, 32);
@@ -254,8 +253,7 @@ int IpTunnel_connectTo(uint8_t publicKeyOfNodeToConnectTo[32], struct IpTunnel*
  */
 int IpTunnel_removeConnection(int connectionNumber, struct IpTunnel* tunnel)
 {
-    struct IpTunnel_pvt* context = (struct IpTunnel_pvt*) tunnel;
-    Assert_true(context->identity == &IpTunnel_IDENTITY);
+    //struct IpTunnel_pvt* context = Identity_check(tunnel);
 
     return 0;
 }
@@ -362,9 +360,9 @@ static int incomingAddresses(Dict* d,
     if (number != conn->number) {
         for (int i = 0; i < (int)context->pub.connectionList.count; i++) {
             if (context->pub.connectionList.connections[i].number == number) {
-                if (memcmp(conn->header.nodeKey,
-                           context->pub.connectionList.connections[i].header.nodeKey,
-                           32))
+                if (Bits_memcmp(conn->header.nodeKey,
+                                context->pub.connectionList.connections[i].header.nodeKey,
+                                32))
                 {
                     Log_info(context->logger, "txid doesn't match origin");
                     return Error_INVALID;
@@ -486,7 +484,7 @@ static struct IpTunnel_Connection* getConnection(struct IpTunnel_Connection* con
             : ((conn->isOutgoing) ? DESTINATION : source);
 
         uint8_t* connectionAddr = (sourceAndDestIp6) ? conn->connectionIp6 : conn->connectionIp4;
-        if (!memcmp(compareAddr, connectionAddr, length)) {
+        if (!Bits_memcmp(compareAddr, connectionAddr, length)) {
             return conn;
         }
         conn++;
@@ -497,8 +495,7 @@ static struct IpTunnel_Connection* getConnection(struct IpTunnel_Connection* con
 
 static uint8_t incomingFromTun(struct Message* message, struct Interface* tunIf)
 {
-    struct IpTunnel_pvt* context = (struct IpTunnel_pvt*) tunIf;
-    Assert_true(context->identity = &IpTunnel_IDENTITY);
+    struct IpTunnel_pvt* context = Identity_check(tunIf);
 
     if (message->length < 20) {
         Log_debug(context->logger, "Dropping runt.");
@@ -577,8 +574,7 @@ static uint8_t ip4FromNode(struct Message* message,
 static uint8_t incomingFromNode(struct Message* message, struct Interface* nodeIf)
 {
     struct IpTunnel_pvt* context =
-        (struct IpTunnel_pvt*) (((char*)nodeIf) - offsetof(struct IpTunnel, nodeInterface));
-    Assert_true(context->identity = &IpTunnel_IDENTITY);
+        Identity_check((((char*)nodeIf) - offsetof(struct IpTunnel, nodeInterface)));
 
     Assert_true(message->length >= IpTunnel_PacketInfoHeader_SIZE);
     struct IpTunnel_PacketInfoHeader* header = (struct IpTunnel_PacketInfoHeader*) message->bytes;
@@ -647,12 +643,12 @@ struct IpTunnel* IpTunnel_new(struct Log* logger,
                 .tunInterface = { .sendMessage = incomingFromTun },
                 .nodeInterface = { .sendMessage = incomingFromNode }
             },
-            .identity = &IpTunnel_IDENTITY,
             .allocator = alloc,
             .logger = logger,
             .rand = rand
         });
     context->timeout = Timeout_setInterval(timeout, context, 10000, eventBase, alloc);
+    Identity_set(context);
 
     return &context->pub;
 }

+ 0 - 1
tunnel/IpTunnel_admin.c

@@ -22,7 +22,6 @@
 #include "tunnel/IpTunnel.h"
 #include "tunnel/IpTunnel_admin.h"
 
-#include <string.h>
 #include <stddef.h>
 #include <event2/event.h>
 

+ 27 - 0
tunnel/test/CMakeLists.txt

@@ -0,0 +1,27 @@
+# You may redistribute this program and/or modify it under the terms of
+# the GNU General Public License as published by the Free Software Foundation,
+# either version 3 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+add_executable(IpTunnel_test
+    IpTunnel_test.c
+)
+
+target_link_libraries(IpTunnel_test
+    cjdns-tunnel-iptunnel
+    cjdbenc
+    cjdmemory
+    crypto
+    cjdns-util-log
+    cjdbenc_StandardBencSerializer
+    cjdns-crypto-random
+    cjdns-util-events-libevent
+)
+add_test(IpTunnel_test IpTunnel_test)

+ 151 - 0
tunnel/test/IpTunnel_test.c

@@ -0,0 +1,151 @@
+/* vim: set expandtab ts=4 sw=4: */
+/*
+ * You may redistribute this program and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#define string_strcpy
+#define string_strlen
+#include "memory/Allocator.h"
+#include "memory/MallocAllocator.h"
+#include "io/FileWriter.h"
+#include "util/log/Log.h"
+#include "util/log/WriterLog.h"
+#include "util/events/EventBase.h"
+#include "crypto/Random.h"
+#include "crypto/AddressCalc.h"
+#include "tunnel/IpTunnel.h"
+#include "util/platform/libc/string.h"
+#include "util/Bits.h"
+#include "util/Checksum.h"
+#include "wire/Message.h"
+#include "wire/Headers.h"
+
+static uint8_t* fakePubKey = (uint8_t*) "abcdefghijklmnopqrstuvwxyz012345";
+static uint8_t nodeCjdnsIp6[16];
+static uint8_t* fakeIp6ToGive = (uint8_t*) "0123456789abcdef";
+static int called = 0;
+
+uint8_t responseWithIpCallback(struct Message* message, struct Interface* iface)
+{
+    struct IpTunnel_PacketInfoHeader* pi = (struct IpTunnel_PacketInfoHeader*) message->bytes;
+    Assert_always(!Bits_memcmp(nodeCjdnsIp6, pi->nodeIp6Addr, 16));
+    Assert_always(!Bits_memcmp(fakePubKey, pi->nodeKey, 32));
+
+    Message_shift(message, -IpTunnel_PacketInfoHeader_SIZE);
+    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;
+    Assert_always(Headers_getIpVersion(ip) == 6);
+    uint16_t length = Endian_bigEndianToHost16(ip->payloadLength_be);
+    Assert_always(length + Headers_IP6Header_SIZE == message->length);
+    Assert_always(ip->nextHeader == 17);
+    Assert_always(Bits_isZero(ip->sourceAddr, 32));
+
+    Message_shift(message, -Headers_IP6Header_SIZE);
+    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes;
+    Assert_always(!Checksum_udpIp6(ip->sourceAddr, message->bytes, length));
+
+    Assert_always(uh->sourceAndDestPorts == 0);
+    Assert_always(Endian_bigEndianToHost16(uh->length_be) + Headers_UDPHeader_SIZE == length);
+
+    Message_shift(message, -Headers_UDPHeader_SIZE);
+    char* expectedResponse =
+        "d"
+          "9:addresses" "d"
+            "3:ip6" "16:0123456789abcdef"
+          "e"
+          "4:txid" "4:abcd"
+        "e";
+    Assert_always(message->length == strlen(expectedResponse));
+    Assert_always(!Bits_memcmp(message->bytes, expectedResponse, message->length));
+    called = 1;
+    return 0;
+}
+
+uint8_t messageToTun(struct Message* message, struct Interface* iface)
+{
+    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;
+    Assert_always(Headers_getIpVersion(ip) == 6);
+    uint16_t length = Endian_bigEndianToHost16(ip->payloadLength_be);
+    Assert_always(length + Headers_IP6Header_SIZE == message->length);
+    Assert_always(ip->nextHeader == 17);
+    Assert_always(!Bits_memcmp(ip->sourceAddr, fakeIp6ToGive, 16));
+    called = 1;
+    return 0;
+}
+
+int main()
+{
+    AddressCalc_addressForPublicKey(nodeCjdnsIp6, fakePubKey);
+    struct Allocator* alloc = MallocAllocator_new(1<<20);
+    struct Writer* w = FileWriter_new(stdout, alloc);
+    struct Log* logger = WriterLog_new(w, alloc);
+    struct Random* rand = Random_new(alloc, NULL);
+    struct EventBase* eb = EventBase_new(alloc);
+
+    struct IpTunnel* ipTun = IpTunnel_new(logger, eb, alloc, rand);
+    IpTunnel_allowConnection(fakePubKey, fakeIp6ToGive, NULL, ipTun);
+
+    struct Message* message;
+    Message_STACK(message, 64, 512);
+
+    const char* requestForAddresses =
+        "d"
+          "1:q" "21:IpTunnel_getAddresses"
+          "4:txid" "4:abcd"
+        "e";
+    strcpy((char*)message->bytes, requestForAddresses);
+    message->length = strlen(requestForAddresses);
+
+    Message_shift(message, Headers_UDPHeader_SIZE);
+    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes;
+
+    uh->sourceAndDestPorts = 0;
+    uh->length_be = Endian_hostToBigEndian16(message->length - Headers_UDPHeader_SIZE);
+    uint16_t* checksum = &uh->checksum_be;
+    uint32_t length = message->length;
+
+    Message_shift(message, Headers_IP6Header_SIZE);
+    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;
+
+    ip->versionClassAndFlowLabel = 0;
+    ip->flowLabelLow_be = 0;
+    ip->payloadLength_be = Endian_hostToBigEndian16(length);
+    ip->nextHeader = 17;
+    ip->hopLimit = 255;
+    Bits_memset(ip->sourceAddr, 0, 32);
+    Headers_setIpVersion(ip);
+
+    Message_shift(message, IpTunnel_PacketInfoHeader_SIZE);
+    struct IpTunnel_PacketInfoHeader* pi = (struct IpTunnel_PacketInfoHeader*) message->bytes;
+
+    Bits_memcpyConst(pi->nodeIp6Addr, nodeCjdnsIp6, 16);
+    Bits_memcpyConst(pi->nodeKey, fakePubKey, 32);
+
+    *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length);
+
+    ipTun->nodeInterface.receiveMessage = responseWithIpCallback;
+    ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface);
+    Assert_always(called);
+    called = 0;
+
+    // Now create a message for someone else.
+    Message_shift(message,
+        Headers_UDPHeader_SIZE
+        + Headers_IP6Header_SIZE
+        + IpTunnel_PacketInfoHeader_SIZE);
+    Bits_memcpyConst(ip->sourceAddr, fakeIp6ToGive, 16);
+    // This can't be zero.
+    Bits_memset(ip->destinationAddr, 1, 16);
+
+    ipTun->tunInterface.receiveMessage = messageToTun;
+    ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface);
+    Assert_true(called);
+}

+ 1 - 1
util/AverageRoller.c

@@ -17,7 +17,7 @@
 #include "util/Time.h"
 
 #include <event2/event.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 
 /** Used to represent the sum and entry count for a given second. */
 struct SumAndEntryCount

+ 27 - 8
util/Bits.h

@@ -73,6 +73,31 @@ static inline bool Bits_isZero(void* buffer, size_t length)
     return true;
 }
 
+
+static inline void* Bits_memmove(void* dest, const void* src, size_t length)
+{
+    void* memmove(void* dest, const void* src, size_t length);
+    return memmove(dest, src, length);
+}
+
+static inline void* Bits_memset(void* location, int byte, size_t count)
+{
+    void* memset(void* location, int byte, size_t count);
+    return memset(location, byte, count);
+}
+
+static inline int Bits_memcmp(const void* loc1, const void* loc2, size_t length)
+{
+    int memcmp(const void* loc1, const void* loc2, size_t length);
+    return memcmp(loc1, loc2, length);
+}
+
+static inline void* Bits_memcpyNoDebug(void* restrict out, const void* restrict in, size_t length)
+{
+    void* memcpy(void* restrict out, const void* restrict in, size_t length);
+    return memcpy(out, in, length);
+}
+
 /**
  * @param out buffer to write to.
  * @param in buffer to read from.
@@ -92,7 +117,7 @@ static inline void* Bits_memcpyDebug(void* out,
     const char* outc = out;
     // Check that pointers don't alias.
     Assert_always(outc < inc || outc >= inc + length);
-    return __builtin_memcpy(out, in, length);
+    return Bits_memcpyNoDebug(out, in, length);
 }
 
 /**
@@ -106,15 +131,9 @@ static inline void* Bits_memcpyDebug(void* out,
 #ifdef Log_DEBUG
     #define Bits_memcpy(a, b, c) Bits_memcpyDebug(a, b, c, __FILE__, __LINE__)
 #else
-    #define Bits_memcpy(a,b,c) __builtin_memcpy(a, b, c)
+    #define Bits_memcpy(a,b,c) Bits_memcpyNoDebug(a,b,c)
 #endif
 
-#define Bits_memmove(a,b,c) __builtin_memmove(a,b,c)
-
-#define Bits_memset(a,b,c) __builtin_memset(a,b,c)
-
-#define Bits_memcmp(a,b,c) __builtin_memcmp(a,b,c)
-
 /**
  * Bits_memcpyConst()
  * Alias to POSIX memcpy(), will not compile unless the number of bytes to be copied

+ 3 - 2
util/Identity.h

@@ -30,13 +30,14 @@
         pointer->Identity_verifier = &Identity_ID
 
     #define Identity_check(pointer) \
-        (pointer); Assert_always(pointer->Identity_verifier == &Identity_ID)
+        ((void*)pointer);           \
+        Assert_always(((Identity_TYPE*)pointer)->Identity_verifier == &Identity_ID)
 
 #else
 
     #define Identity
     #define Identity_set(pointer)
-    #define Identity_check(pointer) (pointer)
+    #define Identity_check(pointer) ((void*)pointer)
 
 #endif
 

+ 1 - 1
util/Process_FreeBSD.c

@@ -18,7 +18,7 @@
 #include "util/Bits.h"
 
 #include <stdint.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <unistd.h>
 #include <sys/sysctl.h> // sysctl()
 #include <sys/param.h> // MAXPATHLEN

+ 1 - 1
util/Process_Illumos.c

@@ -21,7 +21,7 @@
 #include "util/Bits.h"
 
 #include <stdint.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <unistd.h>
 
 int Process_spawn(char* binaryPath, char** args)

+ 1 - 1
util/Process_Linux.c

@@ -17,11 +17,11 @@
 
 #include "memory/Allocator.h"
 #include "memory/MallocAllocator.h"
+#include "util/platform/libc/strlen.h"
 #include "util/Process.h"
 #include "util/Bits.h"
 
 #include <stdint.h>
-#include <string.h>
 #include <unistd.h>
 
 int Process_spawn(char* binaryPath, char** args)

+ 1 - 1
util/Process_OSX.c

@@ -20,7 +20,7 @@
 #include <mach-o/dyld.h> // _NSGetExecutablePath()
 #include <sys/param.h> // MAXPATHLEN
 #include <stdint.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <unistd.h>
 
 int Process_spawn(char* binaryPath, char** args)

+ 1 - 1
util/Process_OpenBSD.c

@@ -19,7 +19,7 @@
 extern const char* __progname;
 
 #include <stdint.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <unistd.h>
 #include <sys/param.h> // MAXPATHLEN
 

+ 1 - 1
util/Process_W32.c

@@ -18,7 +18,7 @@
 #include "util/Process.h"
 #include "util/Bits.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <windows.h>
 
 

+ 1 - 1
util/Security.c

@@ -21,7 +21,7 @@
 #include <sys/types.h>
 #include <pwd.h>
 #include <unistd.h>
-#include <string.h>
+#include "util/platform/libc/string.h"
 
 void Security_setUser(char* userName, struct Log* logger, struct Except* eh)
 {

+ 2 - 1
util/Security_admin.c

@@ -20,7 +20,8 @@
 #include "util/log/Log.h"
 #include "util/Security.h"
 
-#include <string.h>
+#define string_strlen
+#include "util/platform/libc/string.h"
 
 struct Context
 {

+ 3 - 1
util/log/WriterLog.c

@@ -19,7 +19,9 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <string.h>
+#define string_strlen
+#define string_strrchr
+#include "util/platform/libc/string.h"
 #include <strings.h>
 #include <time.h>
 

+ 323 - 0
util/platform/libc/string.h

@@ -0,0 +1,323 @@
+/* vim: set expandtab ts=4 sw=4: */
+/*
+ * You may redistribute this program and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef string_H
+#define string_H
+
+#undef memcpy
+#ifndef string_memcpy
+    #define memcpy string_internal_memcpy
+#endif
+#undef memmove
+#ifndef string_memmove
+    #define memmove string_internal_memmove
+#endif
+#undef memccpy
+#ifndef string_memccpy
+    #define memccpy string_internal_memccpy
+#endif
+#undef memset
+#ifndef string_memset
+    #define memset string_internal_memset
+#endif
+#undef memcmp
+#ifndef string_memcmp
+    #define memcmp string_internal_memcmp
+#endif
+#undef memchr
+#ifndef string_memchr
+    #define memchr string_internal_memchr
+#endif
+#undef strcpy
+#ifndef string_strcpy
+    #define strcpy string_internal_strcpy
+#endif
+#undef strncpy
+#ifndef string_strncpy
+    #define strncpy string_internal_strncpy
+#endif
+#undef strcat
+#ifndef string_strcat
+    #define strcat string_internal_strcat
+#endif
+#undef strncat
+#ifndef string_strncat
+    #define strncat string_internal_strncat
+#endif
+#undef strcmp
+#ifndef string_strcmp
+    #define strcmp string_internal_strcmp
+#endif
+#undef strncmp
+#ifndef string_strncmp
+    #define strncmp string_internal_strncmp
+#endif
+#undef strcoll
+#ifndef string_strcoll
+    #define strcoll string_internal_strcoll
+#endif
+#undef strxfrm
+#ifndef string_strxfrm
+    #define strxfrm string_internal_strxfrm
+#endif
+#undef strcoll_l
+#ifndef string_strcoll_l
+    #define strcoll_l string_internal_strcoll_l
+#endif
+#undef strxfrm_l
+#ifndef string_strxfrm_l
+    #define strxfrm_l string_internal_strxfrm_l
+#endif
+#undef strdup
+#ifndef string_strdup
+    #define strdup string_internal_strdup
+#endif
+#undef strndup
+#ifndef string_strndup
+    #define strndup string_internal_strndup
+#endif
+#undef strchr
+#ifndef string_strchr
+    #define strchr string_internal_strchr
+#endif
+#undef strrchr
+#ifndef string_strrchr
+    #define strrchr string_internal_strrchr
+#endif
+#undef strcspn
+#ifndef string_strcspn
+    #define strcspn string_internal_strcspn
+#endif
+#undef strspn
+#ifndef string_strspn
+    #define strspn string_internal_strspn
+#endif
+#undef strpbrk
+#ifndef string_strpbrk
+    #define strpbrk string_internal_strpbrk
+#endif
+#undef strstr
+#ifndef string_strstr
+    #define strstr string_internal_strstr
+#endif
+#undef strtok
+#ifndef string_strtok
+    #define strtok string_internal_strtok
+#endif
+#undef strtok_r
+#ifndef string_strtok_r
+    #define strtok_r string_internal_strtok_r
+#endif
+#undef strlen
+#ifndef string_strlen
+    #define strlen string_internal_strlen
+#endif
+#undef strnlen
+#ifndef string_strnlen
+    #define strnlen string_internal_strnlen
+#endif
+#undef strerror
+#ifndef string_strerror
+    #define strerror string_internal_strerror
+#endif
+#undef strerror_r
+#ifndef string_strerror_r
+    #define strerror_r string_internal_strerror_r
+#endif
+#undef strerror_l
+#ifndef string_strerror_l
+    #define strerror_l string_internal_strerror_l
+#endif
+#undef bcopy
+#ifndef string_bcopy
+    #define bcopy string_internal_bcopy
+#endif
+#undef bzero
+#ifndef string_bzero
+    #define bzero string_internal_bzero
+#endif
+#undef bcmp
+#ifndef string_bcmp
+    #define bcmp string_internal_bcmp
+#endif
+#undef index
+#ifndef string_index
+    #define index string_internal_index
+#endif
+#undef rindex
+#ifndef string_rindex
+    #define rindex string_internal_rindex
+#endif
+#undef ffs
+#ifndef string_ffs
+    #define ffs string_internal_ffs
+#endif
+#undef strcasecmp
+#ifndef string_strcasecmp
+    #define strcasecmp string_internal_strcasecmp
+#endif
+#undef strncasecmp
+#ifndef string_strncasecmp
+    #define strncasecmp string_internal_strncasecmp
+#endif
+#undef strsep
+#ifndef string_strsep
+    #define strsep string_internal_strsep
+#endif
+#undef strsignal
+#ifndef string_strsignal
+    #define strsignal string_internal_strsignal
+#endif
+#undef stpcpy
+#ifndef string_stpcpy
+    #define stpcpy string_internal_stpcpy
+#endif
+#undef stpncpy
+#ifndef string_stpncpy
+    #define stpncpy string_internal_stpncpy
+#endif
+
+#include <string.h>
+
+#ifndef string_memcpy
+    #undef memcpy
+#endif
+#ifndef string_memmove
+    #undef memmove
+#endif
+#ifndef string_memccpy
+    #undef memccpy
+#endif
+#ifndef string_memset
+    #undef memset
+#endif
+#ifndef string_memcmp
+    #undef memcmp
+#endif
+#ifndef string_memchr
+    #undef memchr
+#endif
+#ifndef string_strcpy
+    #undef strcpy
+#endif
+#ifndef string_strncpy
+    #undef strncpy
+#endif
+#ifndef string_strcat
+    #undef strcat
+#endif
+#ifndef string_strncat
+    #undef strncat
+#endif
+#ifndef string_strcmp
+    #undef strcmp
+#endif
+#ifndef string_strncmp
+    #undef strncmp
+#endif
+#ifndef string_strcoll
+    #undef strcoll
+#endif
+#ifndef string_strxfrm
+    #undef strxfrm
+#endif
+#ifndef string_strcoll_l
+    #undef strcoll_l
+#endif
+#ifndef string_strxfrm_l
+    #undef strxfrm_l
+#endif
+#ifndef string_strdup
+    #undef strdup
+#endif
+#ifndef string_strndup
+    #undef strndup
+#endif
+#ifndef string_strchr
+    #undef strchr
+#endif
+#ifndef string_strrchr
+    #undef strrchr
+#endif
+#ifndef string_strcspn
+    #undef strcspn
+#endif
+#ifndef string_strspn
+    #undef strspn
+#endif
+#ifndef string_strpbrk
+    #undef strpbrk
+#endif
+#ifndef string_strstr
+    #undef strstr
+#endif
+#ifndef string_strtok
+    #undef strtok
+#endif
+#ifndef string_strtok_r
+    #undef strtok_r
+#endif
+#ifndef string_strlen
+    #undef strlen
+#endif
+#ifndef string_strnlen
+    #undef strnlen
+#endif
+#ifndef string_strerror
+    #undef strerror
+#endif
+#ifndef string_strerror_r
+    #undef strerror_r
+#endif
+#ifndef string_strerror_l
+    #undef strerror_l
+#endif
+#ifndef string_bcopy
+    #undef bcopy
+#endif
+#ifndef string_bzero
+    #undef bzero
+#endif
+#ifndef string_bcmp
+    #undef bcmp
+#endif
+#ifndef string_index
+    #undef index
+#endif
+#ifndef string_rindex
+    #undef rindex
+#endif
+#ifndef string_ffs
+    #undef ffs
+#endif
+#ifndef string_strcasecmp
+    #undef strcasecmp
+#endif
+#ifndef string_strncasecmp
+    #undef strncasecmp
+#endif
+#ifndef string_strsep
+    #undef strsep
+#endif
+#ifndef string_strsignal
+    #undef strsignal
+#endif
+#ifndef string_stpcpy
+    #undef stpcpy
+#endif
+#ifndef string_stpncpy
+    #undef stpncpy
+#endif
+
+#endif

+ 20 - 0
util/platform/libc/strlen.h

@@ -0,0 +1,20 @@
+/* vim: set expandtab ts=4 sw=4: */
+/*
+ * You may redistribute this program and/or modify it under the terms of
+ * the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef strlen_H
+#define strlen_H
+
+#define strlen(a) __builtin_strlen(a)
+
+#endif

+ 3 - 3
util/test/Base32_test.c

@@ -14,11 +14,11 @@
  */
 #include "crypto/Random.h"
 #include "memory/BufferAllocator.h"
+#include "util/Bits.h"
 #include "util/Base32.h"
 #include "util/Assert.h"
 
 #include <stdio.h>
-#include <string.h>
 
 int main()
 {
@@ -30,7 +30,7 @@ int main()
     Random_bytes(rand, bytes, 32);
 
     uint8_t base32[64];
-    memset(base32, 0, 64);
+    Bits_memset(base32, 0, 64);
 
     Assert_always(Base32_encode(base32, 64, bytes, 32) == 52);
 
@@ -39,5 +39,5 @@ int main()
     uint8_t bytes2[32];
     Assert_always(Base32_decode(bytes2, 32, base32, 52) == 32);
 
-    Assert_always(memcmp(bytes, bytes2, 32) == 0);
+    Assert_always(Bits_memcmp(bytes, bytes2, 32) == 0);
 }

+ 6 - 2
util/test/Hex_test.c

@@ -12,12 +12,16 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#define string_strlen
+#define string_strstr
+#define string_strcmp
 #include "crypto/Random.h"
 #include "memory/BufferAllocator.h"
+#include "util/platform/libc/string.h"
+#include "util/Bits.h"
 #include "util/Hex.h"
 #include "util/Assert.h"
 
-#include <string.h>
 #include <stdio.h>
 
 int main()
@@ -38,5 +42,5 @@ int main()
     uint8_t bytes2[32];
     Assert_always(Hex_decode(bytes2, 32, hex, 64) == 32);
 
-    Assert_always(memcmp(bytes, bytes2, 32) == 0);
+    Assert_always(Bits_memcmp(bytes, bytes2, 32) == 0);
 }

+ 1 - 1
util/test/Process_test.c

@@ -18,7 +18,7 @@
 #include "util/Process.h"
 #include "util/Pipe.h"
 
-#include <string.h>
+#include "util/platform/libc/string.h"
 #include <unistd.h>
 
 #define MESSAGE "IT WORKS!"