]> git.meshlink.io Git - meshlink/commitdiff
Reorganize structs for better packing and access patterns.
authorGuus Sliepen <guus@meshlink.io>
Fri, 19 Jul 2019 16:23:37 +0000 (18:23 +0200)
committerGuus Sliepen <guus@meshlink.io>
Fri, 19 Jul 2019 16:23:37 +0000 (18:23 +0200)
Used the pahole tool to find gaps in structs. Move the lesser accessed
members to the end of the struct.

src/connection.h
src/edge.h
src/event.c
src/event.h
src/meshlink_internal.h
src/net.h
src/node.h
src/sptps.h

index d9e04f8c9942724e768e106281328ceea96ebd4a..27513e975fbb1ef73e89b7abb573b5041769093c 100644 (file)
 #define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */
 
 typedef struct connection_status_t {
-       unsigned int pinged: 1;                 /* sent ping */
-       unsigned int active: 1;                 /* 1 if active.. */
-       unsigned int connecting: 1;             /* 1 if we are waiting for a non-blocking connect() to finish */
-       unsigned int unused_termreq: 1;         /* the termination of this connection was requested */
-       unsigned int remove_unused: 1;          /* Set to 1 if you want this connection removed */
-       unsigned int timeout_unused: 1;         /* 1 if gotten timeout */
-       unsigned int unused_encryptout: 1;      /* 1 if we can encrypt outgoing traffic */
-       unsigned int unused_decryptin: 1;       /* 1 if we have to decrypt incoming traffic */
-       unsigned int mst: 1;                    /* 1 if this connection is part of a minimum spanning tree */
-       unsigned int control: 1;                /* 1 if this is a control connection */
-       unsigned int pcap: 1;                   /* 1 if this is a control connection requesting packet capture */
-       unsigned int log: 1;                    /* 1 if this is a control connection requesting log dump */
-       unsigned int invitation: 1;             /* 1 if this is an invitation */
-       unsigned int invitation_used: 1;        /* 1 if the invitation has been consumed */
-       unsigned int unused: 19;
+       uint16_t pinged: 1;                 /* sent ping */
+       uint16_t active: 1;                 /* 1 if active.. */
+       uint16_t connecting: 1;             /* 1 if we are waiting for a non-blocking connect() to finish */
+       uint16_t mst: 1;                    /* 1 if this connection is part of a minimum spanning tree */
+       uint16_t control: 1;                /* 1 if this is a control connection */
+       uint16_t pcap: 1;                   /* 1 if this is a control connection requesting packet capture */
+       uint16_t log: 1;                    /* 1 if this is a control connection requesting log dump */
+       uint16_t invitation: 1;             /* 1 if this is an invitation */
+       uint16_t invitation_used: 1;        /* 1 if the invitation has been consumed */
 } connection_status_t;
 
 #include "ecdsa.h"
@@ -56,34 +50,37 @@ typedef struct connection_status_t {
 
 typedef struct connection_t {
        char *name;                     /* name he claims to have */
+       struct node_t *node;            /* node associated with the other end */
 
-       union sockaddr_t address;       /* his real (internet) ip */
-       int protocol_major;             /* used protocol */
-       int protocol_minor;             /* used protocol */
-
-       int socket;                     /* socket used for this connection */
-       uint32_t options;               /* options for this connection */
        connection_status_t status;     /* status info */
-       struct outgoing_t *outgoing;    /* used to keep track of outgoing connections */
+       int socket;                     /* socket used for this connection */
+       union sockaddr_t address;       /* his real (internet) ip */
 
        struct meshlink_handle *mesh;   /* the mesh this connection belongs to */
-       struct node_t *node;            /* node associated with the other end */
-       struct edge_t *edge;            /* edge associated with this connection */
 
-       ecdsa_t *ecdsa;                 /* his public ECDSA key */
+       // I/O
        sptps_t sptps;
-       struct submesh_t *submesh;              /* his submesh handle if available in invitation file */
-
-       int incompression;
-       int outcompression;
-
        struct buffer_t inbuf;
        struct buffer_t outbuf;
        io_t io;                        /* input/output event on this metadata connection */
        int tcplen;                     /* length of incoming TCPpacket */
        int allow_request;              /* defined if there's only one request possible */
-
        time_t last_ping_time;          /* last time we saw some activity from the other end or pinged them */
+
+       struct outgoing_t *outgoing;    /* used to keep track of outgoing connections */
+
+       struct edge_t *edge;            /* edge associated with this connection */
+       struct submesh_t *submesh;      /* his submesh handle if available in invitation file */
+
+       // Only used during authentication
+       ecdsa_t *ecdsa;                 /* his public ECDSA key */
+       int protocol_major;             /* used protocol */
+       int protocol_minor;             /* used protocol */
+
+       // Unused/deprecated
+       uint32_t options;               /* options for this connection */
+       int incompression;
+       int outcompression;
 } connection_t;
 
 extern void init_connections(struct meshlink_handle *mesh);
index cc7a449b7e4b56fe6b962d61b22c5e36f3f27b6f..c86acee34cf781a9305b613f32de006263ec41f9 100644 (file)
@@ -30,11 +30,13 @@ typedef struct edge_t {
        struct node_t *to;
        sockaddr_t address;
 
-       uint32_t options;                       /* options turned on for this edge */
-       int weight;                             /* weight of this edge */
-
        struct connection_t *connection;        /* connection associated with this edge, if available */
        struct edge_t *reverse;                 /* edge in the opposite direction, if available */
+
+       int weight;                             /* weight of this edge */
+
+       // Deprecated
+       uint32_t options;                       /* options turned on for this edge */
 } edge_t;
 
 extern void init_edges(struct meshlink_handle *mesh);
index 3978c30b35b8ac3fdf3d8e832e9f8f215c2625d2..61e6d8d7365893f53fffe50c4c6e07ee3b46ca22 100644 (file)
@@ -181,11 +181,9 @@ static void pipe_init(event_loop_t *loop) {
 }
 
 void signal_trigger(event_loop_t *loop, signal_t *sig) {
-
        uint8_t signum = sig->signum;
        write(loop->pipefd[1], &signum, 1);
        return;
-
 }
 
 void signal_add(event_loop_t *loop, signal_t *sig, signal_cb_t cb, void *data, uint8_t signum) {
index cf3c70a163b531b331bef39a9b797d8cff53d875..245656a338bdf178bad4d0dc01beb25c3c0204e0 100644 (file)
@@ -35,46 +35,46 @@ typedef void (*signal_cb_t)(event_loop_t *loop, void *data);
 typedef struct timeval(*idle_cb_t)(event_loop_t *loop, void *data);
 
 typedef struct io_t {
+       struct splay_node_t node;
        int fd;
        int flags;
        io_cb_t cb;
        void *data;
-       struct splay_node_t node;
 } io_t;
 
 typedef struct timeout_t {
+       struct splay_node_t node;
        struct timeval tv;
        timeout_cb_t cb;
        void *data;
-       struct splay_node_t node;
 } timeout_t;
 
 typedef struct signal_t {
+       struct splay_node_t node;
        int signum;
        signal_cb_t cb;
        void *data;
-       struct splay_node_t node;
 } signal_t;
 
 struct event_loop_t {
-       fd_set readfds;
-       fd_set writefds;
+       void *data;
 
        volatile bool running;
-       struct timeval now;
        bool deletion;
 
-       splay_tree_t ios;
-       splay_tree_t timeouts;
-       splay_tree_t signals;
+       struct timeval now;
 
+       splay_tree_t timeouts;
        idle_cb_t idle_cb;
        void *idle_data;
+       splay_tree_t ios;
+       splay_tree_t signals;
+
+       fd_set readfds;
+       fd_set writefds;
 
        io_t signalio;
        int pipefd[2];
-
-       void *data;
 };
 
 extern void io_add(event_loop_t *loop, io_t *io, io_cb_t cb, void *data, int fd, int flags);
index b31c16eb1cc3b92fef8bd1373f9c07573a11e2d9..c711aa57d8863eb67b2ee82852a39d00dd842319 100644 (file)
@@ -35,7 +35,7 @@
 
 #include <pthread.h>
 
-#define MAXSOCKETS 8    /* Probably overkill... */
+#define MAXSOCKETS 4    /* Probably overkill... */
 
 static const char meshlink_invitation_label[] = "MeshLink invitation";
 static const char meshlink_tcp_label[] = "MeshLink TCP";
@@ -78,43 +78,35 @@ struct meshlink_open_params {
 
 /// A handle for an instance of MeshLink.
 struct meshlink_handle {
+       // public members
        char *name;
        void *priv;
 
-       char *appname;
-       int32_t devclass;
-
-       char *confbase;
-       FILE *conffile;
-
-       meshlink_receive_cb_t receive_cb;
-       meshlink_node_status_cb_t node_status_cb;
+       // private members
+       pthread_mutex_t mesh_mutex;
+       event_loop_t loop;
+       struct node_t *self;
        meshlink_log_cb_t log_cb;
        meshlink_log_level_t log_level;
 
-       meshlink_channel_accept_cb_t channel_accept_cb;
-       meshlink_node_duplicate_cb_t node_duplicate_cb;
-       meshlink_connection_try_cb_t connection_try_cb;
-
-       pthread_t thread;
-       bool threadstarted;
-       pthread_mutex_t mesh_mutex;
-       event_loop_t loop;
-       listen_socket_t listen_socket[MAXSOCKETS];
+       // The most important network-related members come first
        int listen_sockets;
+       listen_socket_t listen_socket[MAXSOCKETS];
+
+       meshlink_receive_cb_t receive_cb;
+       meshlink_queue_t outpacketqueue;
        signal_t datafromapp;
 
-       struct node_t *self;
+       hash_t *node_udp_cache;
 
-       struct splay_tree_t *edges;
        struct splay_tree_t *nodes;
+       struct splay_tree_t *edges;
 
        struct list_t *connections;
        struct list_t *outgoings;
        struct list_t *submeshes;
 
-       meshlink_queue_t outpacketqueue;
-
+       // Meta-connection-related members
        struct splay_tree_t *past_request_tree;
        timeout_t past_request_timeout;
 
@@ -125,42 +117,46 @@ struct meshlink_handle {
        timeout_t pingtimer;
        timeout_t periodictimer;
 
-       char *myport;
-
-       char *proxyhost;
-       char *proxyport;
-       char *proxyuser;
-       char *proxypass;
-       proxytype_t proxytype;
+       struct connection_t *everyone;
 
-       bool discovery;         // Whether Catta is enabled or not
-       bool localdiscovery;
-       sockaddr_t localdiscovery_address;
+       // Infrequently used callbacks
+       meshlink_node_status_cb_t node_status_cb;
+       meshlink_channel_accept_cb_t channel_accept_cb;
+       meshlink_node_duplicate_cb_t node_duplicate_cb;
+       meshlink_connection_try_cb_t connection_try_cb;
 
-       bool default_blacklist;
+       // Mesh parameters
+       char *appname;
+       char *myport;
 
-       hash_t *node_udp_cache;
-       struct connection_t *everyone;
        struct ecdsa *private_key;
        struct ecdsa *invitation_key;
-       int invitation_timeout;
 
+       int32_t devclass;
+
+       int invitation_timeout;
        int pinginterval;       /* seconds between pings */
        int pingtimeout;        /* seconds to wait for response */
        int maxtimeout;
 
-       int sock;
-       sptps_t sptps;
-       char cookie[18], hash[18];
-       char *data;
-       size_t thedatalen;
-       bool success;
-       char line[4096];
-       char buffer[4096];
-       size_t blen;
+       int netns;
 
-       pthread_t discovery_thread;
+       bool default_blacklist;
+       bool discovery;         // Whether Catta is enabled or not
+
+
+       // Configuration
+       char *confbase;
+       FILE *conffile;
+       void *config_key;
+
+       // Thread management
+       pthread_t thread;
+       bool threadstarted;
        bool discovery_threadstarted;
+
+       // Catta
+       pthread_t discovery_thread;
        struct CattaServer *catta_server;
        struct CattaSServiceBrowser *catta_browser;
        struct CattaSimplePoll *catta_poll;
@@ -168,8 +164,25 @@ struct meshlink_handle {
        char *catta_servicetype;
        unsigned int catta_interfaces;
 
-       int netns;
-       void *config_key;
+       // State used for meshlink_join()
+       int sock;
+       char cookie[18], hash[18];
+       bool success;
+       sptps_t sptps;
+       char *data;
+       size_t thedatalen;
+       size_t blen;
+       char line[4096];
+       char buffer[4096];
+
+       // Unused variables
+       char *proxyhost;
+       char *proxyport;
+       char *proxyuser;
+       char *proxypass;
+       proxytype_t proxytype;
+       sockaddr_t localdiscovery_address;
+       bool localdiscovery;
 };
 
 /// A handle for a MeshLink node.
index 9277e6d9dc9ed64c6ebc464772c0250429b53eac..6d27baf4002c8dc9fd797013f5df414805f11c69 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -36,8 +36,8 @@
 #define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128)
 
 typedef struct vpn_packet_t {
-       unsigned int probe: 1;
-       unsigned int tcp: 1;
+       uint16_t probe: 1;
+       int16_t tcp: 1;
        uint16_t len;           /* the actual number of bytes in the `data' field */
        uint8_t data[MAXSIZE];
 } vpn_packet_t;
index 2568f182aaf17cca2ca1d9dcce52f16c2b8a3efa..f03afb2551ace2db99df0d646b1a46b829685e58 100644 (file)
 #include "submesh.h"
 
 typedef struct node_status_t {
-       unsigned int unused_active: 1;          /* 1 if active (not used for nodes) */
-       unsigned int validkey: 1;               /* 1 if we currently have a valid key for him */
-       unsigned int waitingforkey: 1;          /* 1 if we already sent out a request */
-       unsigned int visited: 1;                /* 1 if this node has been visited by one of the graph algorithms */
-       unsigned int reachable: 1;              /* 1 if this node is reachable in the graph */
-       unsigned int indirect: 1;               /* 1 if this node is not directly reachable by us */
-       unsigned int unused_sptps: 1;           /* 1 if this node supports SPTPS */
-       unsigned int udp_confirmed: 1;          /* 1 if the address is one that we received UDP traffic on */
-       unsigned int broadcast: 1;              /* 1 if the next UDP packet should be broadcast to the local network */
-       unsigned int blacklisted: 1;            /* 1 if the node is blacklist so we never want to speak with him anymore */
-       unsigned int destroyed: 1;              /* 1 if the node is being destroyed, deallocate channels when any callback is triggered */
-       unsigned int duplicate: 1;              /* 1 if the node is duplicate, ie. multiple nodes using the same Name are online */
-       unsigned int dirty: 1;                  /* 1 if the configuration of the node is dirty and needs to be written out */
-       unsigned int unused: 19;
+       uint16_t validkey: 1;               /* 1 if we currently have a valid key for him */
+       uint16_t waitingforkey: 1;          /* 1 if we already sent out a request */
+       uint16_t visited: 1;                /* 1 if this node has been visited by one of the graph algorithms */
+       uint16_t reachable: 1;              /* 1 if this node is reachable in the graph */
+       uint16_t indirect: 1;               /* 1 if this node is not directly reachable by us */
+       uint16_t udp_confirmed: 1;          /* 1 if the address is one that we received UDP traffic on */
+       uint16_t broadcast: 1;              /* 1 if the next UDP packet should be broadcast to the local network */
+       uint16_t blacklisted: 1;            /* 1 if the node is blacklist so we never want to speak with him anymore */
+       uint16_t destroyed: 1;              /* 1 if the node is being destroyed, deallocate channels when any callback is triggered */
+       uint16_t duplicate: 1;              /* 1 if the node is duplicate, ie. multiple nodes using the same Name are online */
+       uint16_t dirty: 1;                  /* 1 if the configuration of the node is dirty and needs to be written out */
 } node_status_t;
 
 typedef struct node_t {
+       // Public member variables
        char *name;                             /* name of this node */
        void *priv;
 
-       uint32_t options;                       /* options turned on for this node */
+       // Private member variables
+       node_status_t status;
+       uint16_t minmtu;                        /* Probed minimum MTU */
        int32_t devclass;
 
-       struct meshlink_handle *mesh;           /* The mesh this node belongs to */
-       struct submesh_t *submesh;              /* Nodes Sub-Mesh Handle*/
-
+       // Used for packet I/O
+       sptps_t sptps;
        int sock;                               /* Socket to use for outgoing UDP packets */
        sockaddr_t address;                     /* his real (internet) ip to send UDP packets to */
 
-       node_status_t status;
+       struct utcp *utcp;
+
+       // Traffic counters
+       uint64_t in_packets;
+       uint64_t in_bytes;
+       uint64_t out_packets;
+       uint64_t out_bytes;
+
+       // MTU probes
+       timeout_t mtutimeout;                   /* Probe event */
+       int mtuprobes;                          /* Number of probes */
+       uint16_t mtu;                           /* Maximum size of packets to send to this node */
+       uint16_t maxmtu;                        /* Probed maximum MTU */
+
+       // Used for meta-connection I/O, timeouts
+       struct meshlink_handle *mesh;           /* The mesh this node belongs to */
+       struct submesh_t *submesh;              /* Nodes Sub-Mesh Handle*/
+
        time_t last_state_change;
        time_t last_req_key;
 
        struct ecdsa *ecdsa;                    /* His public ECDSA key */
-       sptps_t sptps;
 
-       int incompression;                      /* Compressionlevel, 0 = no compression */
-       int outcompression;                     /* Compressionlevel, 0 = no compression */
+       struct connection_t *connection;        /* Connection associated with this node (if a direct connection exists) */
+       time_t last_connect_try;
+       time_t last_successfull_connection;
 
+       char *canonical_address;                /* The canonical address of this node, if known */
+       sockaddr_t recent[5];                   /* Recently seen addresses */
+
+       // Graph-related member variables
        int distance;
        struct node_t *nexthop;                 /* nearest node from us to him */
        struct edge_t *prevedge;                /* nearest node from him to us */
@@ -73,25 +93,10 @@ typedef struct node_t {
 
        struct splay_tree_t *edge_tree;         /* Edges with this node as one of the endpoints */
 
-       struct connection_t *connection;        /* Connection associated with this node (if a direct connection exists) */
-       time_t last_connect_try;
-       time_t last_successfull_connection;
-
-       uint16_t mtu;                           /* Maximum size of packets to send to this node */
-       uint16_t minmtu;                        /* Probed minimum MTU */
-       uint16_t maxmtu;                        /* Probed maximum MTU */
-       int mtuprobes;                          /* Number of probes */
-       timeout_t mtutimeout;                   /* Probe event */
-
-       struct utcp *utcp;
-
-       uint64_t in_packets;
-       uint64_t in_bytes;
-       uint64_t out_packets;
-       uint64_t out_bytes;
-
-       char *canonical_address;                /* The canonical address of this node, if known */
-       sockaddr_t recent[5];                   /* Recently seen addresses */
+       // Unused
+       uint32_t options;                       /* options turned on for this node */
+       int incompression;                      /* Compressionlevel, 0 = no compression */
+       int outcompression;                     /* Compressionlevel, 0 = no compression */
 } node_t;
 
 extern void init_nodes(struct meshlink_handle *mesh);
index 11c0d2e66846390df29b12edf4b88a9c45c9ec79..d1e3607eefde3dd0be8c7e5e3cd9f953d125057c 100644 (file)
@@ -43,25 +43,35 @@ typedef bool (*send_data_t)(void *handle, uint8_t type, const void *data, size_t
 typedef bool (*receive_record_t)(void *handle, uint8_t type, const void *data, uint16_t len);
 
 typedef struct sptps {
+       // State
        bool initiator;
        bool datagram;
+       bool instate;
+       bool outstate;
+
        int state;
 
+       // Main member variables
        char *inbuf;
        size_t buflen;
-       uint16_t reclen;
 
-       bool instate;
        chacha_poly1305_ctx_t *incipher;
+       uint32_t replaywin;
        uint32_t inseqno;
        uint32_t received;
-       unsigned int replaywin;
-       char *late;
+       uint16_t reclen;
 
-       bool outstate;
        chacha_poly1305_ctx_t *outcipher;
        uint32_t outseqno;
 
+       char *late;
+
+       // Callbacks
+       void *handle;
+       send_data_t send_data;
+       receive_record_t receive_record;
+
+       // Variables used for the authentication phase
        ecdsa_t *mykey;
        ecdsa_t *hiskey;
        ecdh_t *ecdh;
@@ -72,9 +82,6 @@ typedef struct sptps {
        char *label;
        size_t labellen;
 
-       void *handle;
-       send_data_t send_data;
-       receive_record_t receive_record;
 } sptps_t;
 
 extern unsigned int sptps_replaywin;