return result;
}
-void devtool_get_node_status(meshlink_handle_t *mesh, meshlink_node_t *node, devtool_node_status_t *status) {
- if(!mesh || !node || !status) {
- meshlink_errno = MESHLINK_EINVAL;
- return;
- }
-
+static void devtool_get_reset_node_status(meshlink_handle_t *mesh, meshlink_node_t *node, devtool_node_status_t *status, bool reset) {
node_t *internal = (node_t *)node;
if(pthread_mutex_lock(&mesh->mutex) != 0) {
abort();
}
- memcpy(&status->status, &internal->status, sizeof status->status);
- memcpy(&status->address, &internal->address, sizeof status->address);
- status->mtu = internal->mtu;
- status->minmtu = internal->minmtu;
- status->maxmtu = internal->maxmtu;
- status->mtuprobes = internal->mtuprobes;
- status->in_packets = internal->in_packets;
- status->in_bytes = internal->in_bytes;
- status->out_packets = internal->out_packets;
- status->out_bytes = internal->out_bytes;
-
- // Derive UDP connection status
- if(internal == mesh->self) {
- status->udp_status = DEVTOOL_UDP_WORKING;
- } else if(!internal->status.reachable) {
- status->udp_status = DEVTOOL_UDP_IMPOSSIBLE;
- } else if(!internal->status.validkey) {
- status->udp_status = DEVTOOL_UDP_UNKNOWN;
- } else if(internal->status.udp_confirmed) {
- status->udp_status = DEVTOOL_UDP_WORKING;
- } else if(internal->mtuprobes > 30) {
- status->udp_status = DEVTOOL_UDP_FAILED;
- } else if(internal->mtuprobes > 0) {
- status->udp_status = DEVTOOL_UDP_TRYING;
- } else {
- status->udp_status = DEVTOOL_UDP_UNKNOWN;
+ if(status) {
+ memcpy(&status->status, &internal->status, sizeof status->status);
+ memcpy(&status->address, &internal->address, sizeof status->address);
+ status->mtu = internal->mtu;
+ status->minmtu = internal->minmtu;
+ status->maxmtu = internal->maxmtu;
+ status->mtuprobes = internal->mtuprobes;
+ status->in_data = internal->in_data;
+ status->out_data = internal->out_data;
+ status->in_forward = internal->in_forward;
+ status->out_forward = internal->out_forward;
+ status->in_meta = internal->in_meta;
+ status->out_meta = internal->out_meta;
+
+ // Derive UDP connection status
+ if(internal == mesh->self) {
+ status->udp_status = DEVTOOL_UDP_WORKING;
+ } else if(!internal->status.reachable) {
+ status->udp_status = DEVTOOL_UDP_IMPOSSIBLE;
+ } else if(!internal->status.validkey) {
+ status->udp_status = DEVTOOL_UDP_UNKNOWN;
+ } else if(internal->status.udp_confirmed) {
+ status->udp_status = DEVTOOL_UDP_WORKING;
+ } else if(internal->mtuprobes > 30) {
+ status->udp_status = DEVTOOL_UDP_FAILED;
+ } else if(internal->mtuprobes > 0) {
+ status->udp_status = DEVTOOL_UDP_TRYING;
+ } else {
+ status->udp_status = DEVTOOL_UDP_UNKNOWN;
+ }
+ }
+
+ if(reset) {
+ internal->in_data = 0;
+ internal->out_data = 0;
+ internal->in_forward = 0;
+ internal->out_forward = 0;
+ internal->in_meta = 0;
+ internal->out_meta = 0;
}
pthread_mutex_unlock(&mesh->mutex);
}
+void devtool_get_node_status(meshlink_handle_t *mesh, meshlink_node_t *node, devtool_node_status_t *status) {
+ if(!mesh || !node || !status) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ devtool_get_reset_node_status(mesh, node, status, false);
+}
+
+void devtool_reset_node_counters(meshlink_handle_t *mesh, meshlink_node_t *node, devtool_node_status_t *status) {
+ if(!mesh || !node) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ devtool_get_reset_node_status(mesh, node, status, true);
+}
+
meshlink_submesh_t **devtool_get_all_submeshes(meshlink_handle_t *mesh, meshlink_submesh_t **submeshes, size_t *nmemb) {
if(!mesh || !nmemb || (*nmemb && !submeshes)) {
meshlink_errno = MESHLINK_EINVAL;
uint16_t minmtu;
uint16_t maxmtu;
int mtuprobes;
+
enum {
DEVTOOL_UDP_FAILED = -2, /// UDP tried but failed
DEVTOOL_UDP_IMPOSSIBLE = -1, /// UDP not possible (node unreachable)
DEVTOOL_UDP_TRYING, /// UDP detection in progress
DEVTOOL_UDP_WORKING, /// UDP communication established
} udp_status;
- uint64_t in_packets;
- uint64_t in_bytes;
- uint64_t out_packets;
- uint64_t out_bytes;
+
+ uint64_t in_data; /// Bytes received from channels
+ uint64_t out_data; /// Bytes sent via channels
+ uint64_t in_forward; /// Bytes received for channels that need to be forwarded to other nodes
+ uint64_t out_forward; /// Bytes forwarded from channel from other nodes
+ uint64_t in_meta; /// Bytes received from meta-connections, heartbeat packets etc.
+ uint64_t out_meta; /// Bytes sent on meta-connections, heartbeat packets etc.
};
/// Get the status of a node.
*/
void devtool_get_node_status(meshlink_handle_t *mesh, meshlink_node_t *node, devtool_node_status_t *status);
+/// Reset the traffic counters of a node.
+/** This function resets the byte counters for the given node to zero.
+ * It also returns the status containing the counters right before they are zeroed.
+ *
+ * @param mesh A handle which represents an instance of MeshLink.
+ * @param node A pointer to a meshlink_node_t.
+ * @param status A pointer to a devtools_node_status_t variable that has
+ * to be provided by the caller.
+ * The contents of this variable will be changed to reflect
+ * the current status of the node before the counters are zeroed.
+ * If a NULL pointers is passed, no status will be written.
+ */
+void devtool_reset_node_counters(meshlink_handle_t *mesh, meshlink_node_t *node, devtool_node_status_t *status);
+
/// Get the list of all submeshes of a meshlink instance.
/** This function returns an array of submesh handles.
* These pointers are the same pointers that are present in the submeshes list
for(vpn_packet_t *packet; (packet = meshlink_queue_pop(&mesh->outpacketqueue));) {
logger(mesh, MESHLINK_DEBUG, "Removing packet of %d bytes from packet queue", packet->len);
- mesh->self->in_packets++;
- mesh->self->in_bytes += packet->len;
route(mesh, mesh->self, packet);
free(packet);
}
devtool_get_node_status
devtool_keyrotate_probe
devtool_open_in_netns
+devtool_reset_node_counters
devtool_set_meta_status_cb
devtool_set_inviter_commits_first
devtool_trybind_probe
logger(mesh, MESHLINK_DEBUG, "Received %d bytes of metadata from %s", inlen, c->name);
+ if(c->node) {
+ c->node->in_meta += inlen;
+ }
+
if(c->allow_request == ID) {
buffer_add(&c->inbuf, inbuf, inlen);
logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s", len, n->name);
+ n->out_meta += packet.len;
send_udppacket(mesh, n, &packet);
}
}
static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
+ n->in_meta += len;
+
if(len < 64) {
logger(mesh, MESHLINK_WARNING, "Got too short MTU probe length %d from %s", packet->len, n->name);
return;
bool udp_confirmed = n->status.udp_confirmed;
n->status.udp_confirmed = true;
+ logger(mesh, MESHLINK_DEBUG, "Sending MTU probe reply %d to %s", packet->len, n->name);
+ n->out_meta += packet->len;
send_udppacket(mesh, n, packet);
n->status.udp_confirmed = udp_confirmed;
} else {
if(n->status.blacklisted) {
logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
} else {
- n->in_packets++;
- n->in_bytes += packet->len;
-
route(mesh, n, packet);
}
}
*/
void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
if(n == mesh->self) {
- n->out_packets++;
- n->out_bytes += packet->len;
// TODO: send to application
return;
}
return;
}
- n->out_packets++;
- n->out_bytes += packet->len;
n->status.want_udp = true;
send_sptps_packet(mesh, n, packet);
return;
}
+ if(c->node) {
+ c->node->out_meta += outlen;
+ }
+
buffer_read(&c->outbuf, outlen);
if(!c->outbuf.len) {
struct utcp *utcp;
// Traffic counters
- uint64_t in_packets;
- uint64_t in_bytes;
- uint64_t out_packets;
- uint64_t out_bytes;
+ uint64_t in_data; /* Bytes received from channels */
+ uint64_t out_data; /* Bytes sent via channels */
+ uint64_t in_forward; /* Bytes received for channels that need to be forwarded to other nodes */
+ uint64_t out_forward; /* Bytes forwarded from channel from other nodes */
+ uint64_t in_meta; /* Bytes received from meta-connections, heartbeat packets etc. */
+ uint64_t out_meta; /* Bytes sent on meta-connections, heartbeat packets etc. */
// MTU probes
timeout_t mtutimeout; /* Probe event */
return true;
}
+ size_t len = strlen(request);
+ from->in_forward += len;
+ to->out_forward += len;
+
send_request(mesh, to->nexthop->connection, NULL, "%s", request);
}
return false;
}
+ /* TODO: find a good way to avoid the use of strlen() */
+ size_t len = strlen(request);
+ from->in_forward += len;
+ to->out_forward += len;
+
/* Append the known UDP address of the from node, if we have a confirmed one */
if(!*address && from->status.udp_confirmed && from->address.sa.sa_family != AF_UNSPEC) {
char *reflexive_address, *reflexive_port;
return;
}
+ size_t len = packet->len - sizeof(*hdr);
+
+ // Channel traffic accounting
+ if(source == mesh->self) {
+ dest->out_data += len;
+ }
+
if(dest == mesh->self) {
+ source->in_data += len;
const void *payload = packet->data + sizeof(*hdr);
- size_t len = packet->len - sizeof(*hdr);
char hex[len * 2 + 1];