Improve use of compiler attributes
authorKirill Isakov <bootctl@gmail.com>
Tue, 26 Apr 2022 18:50:55 +0000 (00:50 +0600)
committerKirill Isakov <bootctl@gmail.com>
Thu, 28 Apr 2022 19:18:39 +0000 (01:18 +0600)
Mark some constructor/destructor pairs, add format attributes where they
were missing, and fix new warnings.

38 files changed:
src/address_cache.c
src/address_cache.h
src/bsd/tunemu.c
src/chacha-poly1305/chacha-poly1305.h
src/cipher.c
src/cipher.h
src/conf.c
src/conf.h
src/connection.c
src/connection.h
src/digest.c
src/digest.h
src/dropin.h
src/ecdh.h
src/ecdsa.h
src/ecdsagen.h
src/ed25519/ecdsa.c
src/edge.h
src/fsck.c
src/have.h
src/keys.c
src/keys.h
src/list.h
src/meson.build
src/net.h
src/net_setup.c
src/netutl.h
src/node.c
src/node.h
src/protocol_auth.c
src/protocol_key.c
src/rsa.h
src/rsagen.h
src/splay_tree.h
src/subnet.h
src/tincctl.c
src/tincctl.h
src/utils.h

index a414f46..d9996fb 100644 (file)
@@ -213,7 +213,9 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) {
        }
 
        // We're all out of addresses.
-       exit_configuration(&cache->config_tree);
+       exit_configuration(cache->config_tree);
+       cache->config_tree = NULL;
+
        return false;
 }
 
@@ -255,7 +257,8 @@ void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) {
        }
 
        if(cache->config_tree) {
-               exit_configuration(&cache->config_tree);
+               exit_configuration(cache->config_tree);
+               cache->config_tree = NULL;
        }
 
        if(cache->ai) {
@@ -271,7 +274,8 @@ void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) {
 
 void close_address_cache(address_cache_t *cache) {
        if(cache->config_tree) {
-               exit_configuration(&cache->config_tree);
+               exit_configuration(cache->config_tree);
+               cache->config_tree = NULL;
        }
 
        if(cache->ai) {
index 4ce6ec5..1f891c9 100644 (file)
@@ -43,8 +43,8 @@ typedef struct address_cache_t {
 void add_recent_address(address_cache_t *cache, const sockaddr_t *sa);
 const sockaddr_t *get_recent_address(address_cache_t *cache);
 
-address_cache_t *open_address_cache(struct node_t *node);
-void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa);
 void close_address_cache(address_cache_t *cache);
+address_cache_t *open_address_cache(node_t *node) ATTR_DEALLOCATOR(close_address_cache);
+void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa);
 
 #endif
index 6867c47..4e3fbc7 100644 (file)
@@ -80,6 +80,7 @@ static pcap_t *pcap = NULL;
 static size_t data_buffer_length = 0;
 static uint8_t *data_buffer = NULL;
 
+static void tun_error(char *format, ...) ATTR_FORMAT(printf, 1, 2);
 static void tun_error(char *format, ...) {
        va_list vl;
        va_start(vl, format);
index b558e45..e75d984 100644 (file)
@@ -5,8 +5,8 @@
 
 typedef struct chacha_poly1305_ctx chacha_poly1305_ctx_t;
 
-extern chacha_poly1305_ctx_t *chacha_poly1305_init(void);
 extern void chacha_poly1305_exit(chacha_poly1305_ctx_t *);
+extern chacha_poly1305_ctx_t *chacha_poly1305_init(void) ATTR_DEALLOCATOR(chacha_poly1305_exit);
 extern bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const uint8_t *key);
 
 extern bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen);
index 5ac790a..4e4fb9c 100644 (file)
@@ -28,11 +28,10 @@ cipher_t *cipher_alloc(void) {
        return xzalloc(sizeof(cipher_t));
 }
 
-void cipher_free(cipher_t **cipher) {
-       if(cipher && *cipher) {
-               cipher_close(*cipher);
-               free(*cipher);
-               *cipher = NULL;
+void cipher_free(cipher_t *cipher) {
+       if(cipher) {
+               cipher_close(cipher);
+               free(cipher);
        }
 }
 
index 7911455..116a031 100644 (file)
@@ -36,8 +36,8 @@
 #error Incorrect cryptographic library, please reconfigure.
 #endif
 
-extern cipher_t *cipher_alloc(void) ATTR_MALLOC;
-extern void cipher_free(cipher_t **cipher);
+extern void cipher_free(cipher_t *cipher);
+extern cipher_t *cipher_alloc(void) ATTR_MALLOC ATTR_DEALLOCATOR(cipher_free);
 extern bool cipher_open_by_name(cipher_t *cipher, const char *name);
 extern bool cipher_open_by_nid(cipher_t *cipher, nid_t nid);
 extern void cipher_close(cipher_t *cipher);
index c8cb141..d4c76ec 100644 (file)
@@ -87,9 +87,8 @@ void init_configuration(splay_tree_t *tree) {
        tree->delete = (splay_action_t) free_config;
 }
 
-void exit_configuration(splay_tree_t **config_tree) {
-       splay_delete_tree(*config_tree);
-       *config_tree = NULL;
+void exit_configuration(splay_tree_t *config_tree) {
+       splay_delete_tree(config_tree);
 }
 
 config_t *new_config(void) {
index 3cf677d..d01a237 100644 (file)
@@ -40,11 +40,11 @@ extern int maxtimeout;
 extern bool bypass_security;
 extern list_t cmdline_conf;
 
-extern splay_tree_t *create_configuration(void);
+extern void exit_configuration(splay_tree_t *config_tree);
+extern splay_tree_t *create_configuration(void) ATTR_MALLOC ATTR_DEALLOCATOR(exit_configuration);
 extern void init_configuration(splay_tree_t *);
-extern void exit_configuration(splay_tree_t **config_tree);
-extern config_t *new_config(void) ATTR_MALLOC;
 extern void free_config(config_t *config);
+extern config_t *new_config(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_config);
 extern void config_add(splay_tree_t *config_tree, config_t *config);
 extern config_t *lookup_config(splay_tree_t *config_tree, const char *variable);
 extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config);
index 533e024..4f8d4fd 100644 (file)
@@ -148,7 +148,8 @@ void free_connection(connection_t *c) {
        free(c->hostname);
 
        if(c->config_tree) {
-               exit_configuration(&c->config_tree);
+               exit_configuration(c->config_tree);
+               c->config_tree = NULL;
        }
 
        free(c);
index 23bde77..600c954 100644 (file)
@@ -79,7 +79,7 @@ typedef struct legacy_ctx_t {
        legacy_crypto_t out;           /* cipher/digest we will use to send data to him */
 } legacy_ctx_t;
 
-legacy_ctx_t *new_legacy_ctx(rsa_t *rsa) ATTR_MALLOC;
+legacy_ctx_t *new_legacy_ctx(rsa_t *rsa);
 void free_legacy_ctx(legacy_ctx_t *ctx);
 #endif
 
@@ -131,8 +131,8 @@ extern connection_t *everyone;
 
 extern void init_connections(void);
 extern void exit_connections(void);
-extern connection_t *new_connection(void) ATTR_MALLOC;
 extern void free_connection(connection_t *c);
+extern connection_t *new_connection(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_connection);
 extern void connection_add(connection_t *c);
 extern void connection_del(connection_t *c);
 extern bool dump_connections(struct connection_t *c);
index 4ef98cd..15a111a 100644 (file)
@@ -28,11 +28,10 @@ digest_t *digest_alloc(void) {
        return xzalloc(sizeof(digest_t));
 }
 
-void digest_free(digest_t **digest) {
-       if(digest && *digest) {
-               digest_close(*digest);
-               free(*digest);
-               *digest = NULL;
+void digest_free(digest_t *digest) {
+       if(digest) {
+               digest_close(digest);
+               free(digest);
        }
 }
 
index fdb1be2..08c5141 100644 (file)
@@ -39,8 +39,8 @@ typedef struct digest digest_t;
 
 extern bool digest_open_by_name(digest_t *digest, const char *name, size_t maclength);
 extern bool digest_open_by_nid(digest_t *digest, nid_t nid, size_t maclength);
-extern digest_t *digest_alloc(void) ATTR_MALLOC;
-extern void digest_free(digest_t **digest);
+extern void digest_free(digest_t *digest);
+extern digest_t *digest_alloc(void) ATTR_MALLOC ATTR_DEALLOCATOR(digest_free);
 extern void digest_close(digest_t *digest);
 extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) ATTR_WARN_UNUSED;
 extern bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *digestdata) ATTR_WARN_UNUSED;
index f020f21..6fa7a9d 100644 (file)
@@ -26,8 +26,8 @@ extern int daemon(int, int);
 #endif
 
 #ifndef HAVE_ASPRINTF
-extern int asprintf(char **, const char *, ...);
-extern int vasprintf(char **, const char *, va_list ap);
+extern int asprintf(char **, const char *, ...) ATTR_FORMAT(printf, 2, 3);
+extern int vasprintf(char **, const char *, va_list ap) ATTR_FORMAT(printf, 2, 0);
 #endif
 
 #ifndef HAVE_GETTIMEOFDAY
index 4cd8586..98ddb71 100644 (file)
@@ -29,8 +29,8 @@
 typedef struct ecdh ecdh_t;
 #endif
 
-extern ecdh_t *ecdh_generate_public(void *pubkey) ATTR_MALLOC;
-extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) ATTR_WARN_UNUSED;
 extern void ecdh_free(ecdh_t *ecdh);
+extern ecdh_t *ecdh_generate_public(void *pubkey) ATTR_MALLOC ATTR_DEALLOCATOR(ecdh_free);
+extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) ATTR_WARN_UNUSED;
 
 #endif
index 659d559..44e2ff8 100644 (file)
 typedef struct ecdsa ecdsa_t;
 #endif
 
-extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) ATTR_MALLOC;
-extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa);
-extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) ATTR_MALLOC;
-extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) ATTR_MALLOC;
+extern void ecdsa_free(ecdsa_t *ecdsa);
+extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
+extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
+extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
+extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) ATTR_MALLOC;
 extern size_t ecdsa_size(ecdsa_t *ecdsa);
 extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) ATTR_WARN_UNUSED;
 extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) ATTR_WARN_UNUSED;
 extern bool ecdsa_active(ecdsa_t *ecdsa);
-extern void ecdsa_free(ecdsa_t *ecdsa);
 
 #endif
index 1132dd6..c3ba0d5 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "ecdsa.h"
 
-extern ecdsa_t *ecdsa_generate(void) ATTR_MALLOC;
+extern ecdsa_t *ecdsa_generate(void) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
 extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) ATTR_WARN_UNUSED;
 extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) ATTR_WARN_UNUSED;
 
index 28daf4a..1ba01cf 100644 (file)
@@ -32,6 +32,11 @@ typedef struct {
 #include "../utils.h"
 #include "../xalloc.h"
 
+static ecdsa_t *ecdsa_new(void) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
+static ecdsa_t *ecdsa_new(void) {
+       return xzalloc(sizeof(ecdsa_t));
+}
+
 // Get and set ECDSA keys
 //
 ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
@@ -42,7 +47,7 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
                return 0;
        }
 
-       ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
+       ecdsa_t *ecdsa = ecdsa_new();
        len = b64decode_tinc(p, ecdsa->public, len);
 
        if(len != 32) {
@@ -123,7 +128,7 @@ exit:
 }
 
 ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) {
-       ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
+       ecdsa_t *ecdsa = ecdsa_new();
 
        if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) {
                return ecdsa;
@@ -134,7 +139,7 @@ ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) {
 }
 
 ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
-       ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa));
+       ecdsa_t *ecdsa = ecdsa_new();
 
        if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) {
                return ecdsa;
index 3430eb1..3b4dbb2 100644 (file)
@@ -42,8 +42,8 @@ typedef struct edge_t {
 extern splay_tree_t edge_weight_tree;          /* Tree with all known edges sorted on weight */
 
 extern void exit_edges(void);
-extern edge_t *new_edge(void) ATTR_MALLOC;
 extern void free_edge(edge_t *e);
+extern edge_t *new_edge(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_edge);
 extern void init_edge_tree(splay_tree_t *tree);
 extern void edge_add(edge_t *e);
 extern void edge_del(edge_t *e);
index 28da620..8d818a3 100644 (file)
@@ -536,8 +536,7 @@ static bool check_public_keys(splay_tree_t *config, const char *name, rsa_t *rsa
                fprintf(stderr, "WARNING: cannot read %s\n", host_file);
        }
 
-       ecdsa_t *ec_pub = NULL;
-       read_ecdsa_public_key(&ec_pub, &config, name);
+       ecdsa_t *ec_pub = read_ecdsa_public_key(&config, name);
 
        bool success = true;
 #ifndef DISABLE_LEGACY
index d176098..a155b04 100644 (file)
 #endif
 #endif
 
+#if defined(HAVE_ATTR_MALLOC_WITH_ARG)
+#define ATTR_DEALLOCATOR(dealloc) __attribute__((__malloc__(dealloc)))
+#else
+#define ATTR_DEALLOCATOR(dealloc)
+#endif
+
 #ifdef HAVE_ATTR_MALLOC
 #define ATTR_MALLOC __attribute__((__malloc__))
 #else
index 84bd071..5fe51ae 100644 (file)
@@ -162,11 +162,7 @@ ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile) {
        return key;
 }
 
-bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const char *name) {
-       if(ecdsa_active(*ecdsa)) {
-               return true;
-       }
-
+ecdsa_t *read_ecdsa_public_key(splay_tree_t **config_tree, const char *name) {
        FILE *fp;
        char *fname;
        char *p;
@@ -175,16 +171,16 @@ bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const ch
                *config_tree = create_configuration();
 
                if(!read_host_config(*config_tree, name, true)) {
-                       return false;
+                       return NULL;
                }
        }
 
        /* First, check for simple Ed25519PublicKey statement */
 
        if(get_config_string(lookup_config(*config_tree, "Ed25519PublicKey"), &p)) {
-               *ecdsa = ecdsa_set_base64_public_key(p);
+               ecdsa_t *ecdsa = ecdsa_set_base64_public_key(p);
                free(p);
-               return *ecdsa != NULL;
+               return ecdsa;
        }
 
        /* Else, check for Ed25519PublicKeyFile statement and read it */
@@ -199,19 +195,19 @@ bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const ch
                logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s",
                       fname, strerror(errno));
                free(fname);
-               return false;
+               return NULL;
        }
 
-       *ecdsa = ecdsa_read_pem_public_key(fp);
+       ecdsa_t *ecdsa = ecdsa_read_pem_public_key(fp);
 
-       if(!*ecdsa && errno != ENOENT) {
+       if(!ecdsa && errno != ENOENT) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname);
        }
 
        fclose(fp);
        free(fname);
 
-       return *ecdsa != NULL;
+       return ecdsa;
 }
 
 #ifndef DISABLE_LEGACY
@@ -321,7 +317,7 @@ rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name) {
        if(!fp) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
                free(fname);
-               return false;
+               return NULL;
        }
 
        rsa_t *rsa = rsa_read_pem_public_key(fp);
index 1e0dc15..d7ab338 100644 (file)
@@ -7,12 +7,12 @@
 
 extern bool disable_old_keys(const char *filename, const char *what);
 
-extern ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile);
-extern bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const char *name);
+extern ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
+extern ecdsa_t *read_ecdsa_public_key(splay_tree_t **config_tree, const char *name) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
 
 #ifndef DISABLE_LEGACY
-extern rsa_t *read_rsa_private_key(splay_tree_t *config, char **keyfile);
-extern rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name);
+extern rsa_t *read_rsa_private_key(splay_tree_t *config, char **keyfile) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free);
+extern rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free);
 #endif
 
 #endif // TINC_KEYS_H
index e605ce1..8bd2f16 100644 (file)
@@ -45,10 +45,11 @@ typedef struct list_t {
 
 /* (De)constructors */
 
-extern list_t *list_alloc(list_action_t delete) ATTR_MALLOC;
 extern void list_free(list_t *list);
-extern list_node_t *list_alloc_node(void);
+extern list_t *list_alloc(list_action_t delete) ATTR_MALLOC ATTR_DEALLOCATOR(list_free);
+
 extern void list_free_node(list_t *list, list_node_t *node);
+extern list_node_t *list_alloc_node(void) ATTR_MALLOC ATTR_DEALLOCATOR(list_free_node);
 
 /* Insertion and deletion */
 
index e8c3e53..1d195cf 100644 (file)
@@ -18,6 +18,15 @@ foreach attr : ['malloc', 'nonnull', 'warn_unused_result', 'packed', 'format']
   endif
 endforeach
 
+if cc.compiles('''
+    #include <stdlib.h>
+    extern void *make() __attribute__((malloc(free)));
+    int main(void) { return 0; }
+''')
+  cdata.set('HAVE_ATTR_MALLOC_WITH_ARG', 1,
+            description: 'support for __attribute__((malloc(deallocator)))')
+endif
+
 if cc.compiles('''
     _Static_assert(1, "ok");
     int main(void) { return 0; }
index 8e256ce..888a70c 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -199,7 +199,7 @@ extern void send_packet(struct node_t *n, vpn_packet_t *packet);
 extern void receive_tcppacket(struct connection_t *c, const char *buffer, size_t length);
 extern bool receive_tcppacket_sptps(struct connection_t *c, const char *buffer, size_t length);
 extern void broadcast_packet(const struct node_t *n, vpn_packet_t *packet);
-extern char *get_name(void);
+extern char *get_name(void) ATTR_MALLOC;
 extern void device_enable(void);
 extern void device_disable(void);
 extern bool setup_myself_reloadable(void);
index 40cdaf6..0318613 100644 (file)
@@ -903,7 +903,8 @@ static bool setup_myself(void) {
 
                if(!cipher_open_by_name(myself->incipher, cipher)) {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!");
-                       cipher_free(&myself->incipher);
+                       cipher_free(myself->incipher);
+                       myself->incipher = NULL;
                        free(cipher);
                        return false;
                }
@@ -938,7 +939,8 @@ static bool setup_myself(void) {
 
                if(!digest_open_by_name(myself->indigest, digest, maclength)) {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!");
-                       digest_free(&myself->indigest);
+                       digest_free(myself->indigest);
+                       myself->indigest = NULL;
                        free(digest);
                        return false;
                }
index a1ab660..3218122 100644 (file)
@@ -27,7 +27,7 @@ extern bool hostnames;
 
 // Converts service name (as listed in /etc/services) to port number. Returns 0 on error.
 extern uint16_t service_to_port(const char *service);
-extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) ATTR_MALLOC;
+extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) ATTR_DEALLOCATOR(freeaddrinfo);
 extern sockaddr_t str2sockaddr(const char *address, const char *port);
 extern void sockaddr2str(const sockaddr_t *sa, char **address, char **port);
 extern char *sockaddr2hostname(const sockaddr_t *sa) ATTR_MALLOC;
index 23a0610..8e0f162 100644 (file)
@@ -99,10 +99,10 @@ void free_node(node_t *n) {
        sockaddrfree(&n->address);
 
 #ifndef DISABLE_LEGACY
-       cipher_free(&n->incipher);
-       digest_free(&n->indigest);
-       cipher_free(&n->outcipher);
-       digest_free(&n->outdigest);
+       cipher_free(n->incipher);
+       digest_free(n->indigest);
+       cipher_free(n->outcipher);
+       digest_free(n->outdigest);
 #endif
 
        ecdsa_free(n->ecdsa);
index 1e877ab..fea90d1 100644 (file)
@@ -121,8 +121,8 @@ extern struct node_t *myself;
 extern splay_tree_t node_tree;
 
 extern void exit_nodes(void);
-extern node_t *new_node(void) ATTR_MALLOC;
 extern void free_node(node_t *n);
+extern node_t *new_node(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_node);
 extern void node_add(node_t *n);
 extern void node_del(node_t *n);
 extern node_t *lookup_node(char *name);
index 211d908..d7cbbd4 100644 (file)
@@ -94,7 +94,7 @@ bool send_id(connection_t *c) {
        int minor = 0;
 
        if(experimental) {
-               if(c->outgoing && !read_ecdsa_public_key(&c->ecdsa, &c->config_tree, c->name)) {
+               if(c->outgoing && !ecdsa_active(c->ecdsa) && !(c->ecdsa = read_ecdsa_public_key(&c->config_tree, c->name))) {
                        minor = 1;
                } else {
                        minor = myself->connection->protocol_minor;
@@ -399,8 +399,8 @@ bool id_h(connection_t *c, const char *request) {
                        return false;
                }
 
-               if(experimental) {
-                       read_ecdsa_public_key(&c->ecdsa, &c->config_tree, c->name);
+               if(experimental && !ecdsa_active(c->ecdsa)) {
+                       c->ecdsa = read_ecdsa_public_key(&c->config_tree, c->name);
                }
 
                /* Ignore failures if no key known yet */
@@ -880,7 +880,7 @@ static bool upgrade_h(connection_t *c, const char *request) {
                return false;
        }
 
-       if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(&c->ecdsa, &c->config_tree, c->name)) {
+       if(ecdsa_active(c->ecdsa) || (c->ecdsa = read_ecdsa_public_key(&c->config_tree, c->name))) {
                char *knownkey = ecdsa_get_base64_public_key(c->ecdsa);
                bool different = strcmp(knownkey, pubkey);
                free(knownkey);
index 09acd6a..0890755 100644 (file)
@@ -346,8 +346,11 @@ bool send_ans_key(node_t *to) {
 
        randomize(key, keylen);
 
-       cipher_free(&to->incipher);
-       digest_free(&to->indigest);
+       cipher_free(to->incipher);
+       to->incipher = NULL;
+
+       digest_free(to->indigest);
+       to->indigest = NULL;
 
        if(myself->incipher) {
                to->incipher = cipher_alloc();
@@ -470,8 +473,11 @@ bool ans_key_h(connection_t *c, const char *request) {
 
 #ifndef DISABLE_LEGACY
        /* Don't use key material until every check has passed. */
-       cipher_free(&from->outcipher);
-       digest_free(&from->outdigest);
+       cipher_free(from->outcipher);
+       from->outcipher = NULL;
+
+       digest_free(from->outdigest);
+       from->outdigest = NULL;
 #endif
 
        if(!from->status.sptps) {
@@ -570,7 +576,8 @@ bool ans_key_h(connection_t *c, const char *request) {
                from->outcipher = cipher_alloc();
 
                if(!cipher_open_by_nid(from->outcipher, cipher)) {
-                       cipher_free(&from->outcipher);
+                       cipher_free(from->outcipher);
+                       from->outcipher = NULL;
                        logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
                        return false;
                }
@@ -582,7 +589,8 @@ bool ans_key_h(connection_t *c, const char *request) {
                from->outdigest = digest_alloc();
 
                if(!digest_open_by_nid(from->outdigest, digest, maclength)) {
-                       digest_free(&from->outdigest);
+                       digest_free(from->outdigest);
+                       from->outdigest = NULL;
                        logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
                        return false;
                }
index 8f0c1f6..3cc1e21 100644 (file)
--- a/src/rsa.h
+++ b/src/rsa.h
@@ -27,10 +27,10 @@ typedef struct rsa rsa_t;
 #endif
 
 extern void rsa_free(rsa_t *rsa);
-extern rsa_t *rsa_set_hex_public_key(const char *n, const char *e) ATTR_MALLOC;
-extern rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) ATTR_MALLOC;
-extern rsa_t *rsa_read_pem_public_key(FILE *fp) ATTR_MALLOC;
-extern rsa_t *rsa_read_pem_private_key(FILE *fp) ATTR_MALLOC;
+extern rsa_t *rsa_set_hex_public_key(const char *n, const char *e) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free);
+extern rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free);
+extern rsa_t *rsa_read_pem_public_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free);
+extern rsa_t *rsa_read_pem_private_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free);
 extern size_t rsa_size(const rsa_t *rsa);
 extern bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) ATTR_WARN_UNUSED;
 extern bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) ATTR_WARN_UNUSED;
index 795153d..27c076d 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "rsa.h"
 
-extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) ATTR_MALLOC;
+extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) ATTR_DEALLOCATOR(rsa_free);
 extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) ATTR_WARN_UNUSED;
 extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) ATTR_WARN_UNUSED;
 
index 24645fa..d61b5b0 100644 (file)
@@ -63,11 +63,11 @@ typedef struct splay_tree_t {
 
 /* (De)constructors */
 
-extern splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) ATTR_MALLOC;
 extern void splay_free_tree(splay_tree_t *tree);
+extern splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) ATTR_MALLOC ATTR_DEALLOCATOR(splay_free_tree);
 
-extern splay_node_t *splay_alloc_node(void) ATTR_MALLOC;
 extern void splay_free_node(splay_tree_t *tree, splay_node_t *node);
+extern splay_node_t *splay_alloc_node(void) ATTR_MALLOC ATTR_DEALLOCATOR(splay_free_node);
 
 /* Insertion and deletion */
 
index 016aa54..6220e58 100644 (file)
@@ -65,8 +65,8 @@ typedef struct subnet_t {
 extern splay_tree_t subnet_tree;
 
 extern int subnet_compare(const struct subnet_t *a, const struct subnet_t *b);
-extern subnet_t *new_subnet(void) ATTR_MALLOC;
 extern void free_subnet(subnet_t *subnet);
+extern subnet_t *new_subnet(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_subnet);
 extern void init_subnets(void);
 extern void exit_subnets(void);
 extern void init_subnet_tree(splay_tree_t *tree);
index a18f6ce..b2d98f6 100644 (file)
@@ -1623,7 +1623,8 @@ char *get_my_name(bool verbose) {
        return NULL;
 }
 
-ecdsa_t *get_pubkey(FILE *f) {
+static ecdsa_t *get_pubkey(FILE *f) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
+static ecdsa_t *get_pubkey(FILE *f) {
        char buf[4096];
        char *value;
 
index 4018bb3..9bacc46 100644 (file)
@@ -47,11 +47,10 @@ typedef struct {
 extern const var_t variables[];
 
 extern size_t rstrip(char *value);
-extern char *get_my_name(bool verbose);
+extern char *get_my_name(bool verbose) ATTR_MALLOC;
 extern bool connect_tincd(bool verbose);
 extern bool sendline(int fd, const char *format, ...);
 extern bool recvline(int fd, char *line, size_t len);
 extern int check_port(const char *name);
-extern ecdsa_t *get_pubkey(FILE *f);
 
 #endif
index bd5ce13..f02bb9f 100644 (file)
@@ -72,10 +72,10 @@ static inline suseconds_t jitter(void) {
 
 extern bool check_id(const char *id);
 extern bool check_netname(const char *netname, bool strict);
-char *replace_name(const char *name);
+char *replace_name(const char *name) ATTR_MALLOC;
 
 char *absolute_path(const char *path) ATTR_MALLOC;
 
-extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms);
+extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms) ATTR_DEALLOCATOR(fclose);
 
 #endif