-static uint16_t compress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
- if(level == 0) {
- memcpy(dest, source, len);
- return len;
- } else if(level == 10) {
- return -1;
- } else if(level < 10) {
-#ifdef HAVE_ZLIB
- unsigned long destlen = MAXSIZE;
- if(compress2(dest, &destlen, source, len, level) == Z_OK)
- return destlen;
- else
+/* VPN packet I/O */
+
+#if defined(HAVE_RECVMMSG) || defined(HAVE_SENDMMSG)
+#define MAX_MMSG 32
+
+struct mmsgs {
+ int count;
+ int offset;
+ int fd;
+ struct mmsghdr hdrs[MAX_MMSG];
+ struct iovec iovs[MAX_MMSG];
+ sockaddr_t addrs[MAX_MMSG];
+ vpn_packet_t pkts[MAX_MMSG];
+};
+
+static void init_mmsg_array(struct mmsgs *mmsgs) {
+ mmsgs->count = 0;
+ mmsgs->offset = 0;
+
+ for(int i = 0; i < MAX_MMSG; i++) {
+ mmsgs->hdrs[i].msg_hdr.msg_name = &mmsgs->addrs[i];
+ mmsgs->hdrs[i].msg_hdr.msg_namelen = sizeof(mmsgs->addrs[i]);
+ mmsgs->hdrs[i].msg_hdr.msg_iov = &mmsgs->iovs[i];
+ mmsgs->hdrs[i].msg_hdr.msg_iovlen = 1;
+ mmsgs->iovs[i].iov_base = mmsgs->pkts[i].data;
+ mmsgs->iovs[i].iov_len = MAXSIZE;
+ }
+}
+
+void init_mmsg(meshlink_handle_t *mesh) {
+ mesh->in_mmsgs = xzalloc(sizeof(*mesh->in_mmsgs));
+ mesh->out_mmsgs = xzalloc(sizeof(*mesh->out_mmsgs));
+
+ init_mmsg_array(mesh->in_mmsgs);
+ init_mmsg_array(mesh->out_mmsgs);
+}
+
+void exit_mmsg(meshlink_handle_t *mesh) {
+ free(mesh->out_mmsgs);
+ free(mesh->in_mmsgs);
+
+ mesh->out_mmsgs = NULL;
+ mesh->in_mmsgs = NULL;
+}