From samuel.thibault at ens-lyon.org Wed Dec 2 12:58:26 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Wed, 2 Dec 2015 12:58:26 +0100 Subject: [PATCH] Receive multiple packets at a time Message-ID: <20151202115826.GU3025@var.bordeaux.inria.fr> Hello, Linux has a recvmmsg() system call which allows to achieve several recvfrom() at a time. The patch below makes tinc use it (patch against 1.1-pre11). Basically the patch turns the handle_incoming_vpn_data variables into arrays (of size 1 when recvmmsg is not available, and thus compiled the same as before), and makes the code index into the arrays. You may want to use interdiff -w /dev/null patch to better see what changes the patch makes. With this patch, I saw the non-ciphered bandwidth achieved over direct ethernet improve from 680Mbps to 800Mbps (or conversely, reduce the CPU usage for the same bandwidth). More is yet to come: I'll have a look at extending the tun/tap interface to send/receive several packets at a time, and then also using sendmmsg will again improve performance. Samuel --- configure.ac.original 2015-10-02 17:06:31.250034677 +0200 +++ configure.ac 2015-10-02 17:06:54.147546590 +0200 @@ -187,7 +187,7 @@ dnl Checks for library functions. AC_TYPE_SIGNAL -AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], +AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random recvmmsg select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], [], [], [#include "src/have.h"] ) --- src/net_packet.c.original 2015-10-02 16:26:36.828841493 +0200 +++ src/net_packet.c 2015-10-02 17:15:05.892051503 +0200 @@ -1057,92 +1057,137 @@ return n; } +#ifdef HAVE_RECVMMSG +#define MAX_MSG 256 +#else +#define MAX_MSG 1 +#endif + void handle_incoming_vpn_data(void *data, int flags) { listen_socket_t *ls = data; - vpn_packet_t pkt; + vpn_packet_t pkt[MAX_MSG]; char *hostname; node_id_t nullid = {}; - sockaddr_t addr = {}; - socklen_t addrlen = sizeof addr; + sockaddr_t addr[MAX_MSG] = {}; +#ifdef HAVE_RECVMMSG + struct mmsghdr msg[MAX_MSG]; + struct iovec iov[MAX_MSG]; +#else + socklen_t addrlen = sizeof addr[0]; +#endif node_t *from, *to; bool direct = false; + int num = 1, i; - pkt.offset = 0; - int len = recvfrom(ls->udp.fd, DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); +#ifdef HAVE_RECVMMSG + for (i = 0; i < MAX_MSG; i++) + { + pkt[i].offset = 0; + msg[i].msg_hdr.msg_name = &addr[i].sa; + msg[i].msg_hdr.msg_namelen = sizeof(addr[i]); + iov[i].iov_base = DATA(&pkt[i]); + iov[i].iov_len = MAXSIZE; + msg[i].msg_hdr.msg_iov = &iov[i]; + msg[i].msg_hdr.msg_iovlen = 1; + msg[i].msg_hdr.msg_control = NULL; + msg[i].msg_hdr.msg_controllen = 0; + } - if(len <= 0 || len > MAXSIZE) { + num = recvmmsg(ls->udp.fd, msg, MAX_MSG, MSG_DONTWAIT, NULL); +#else + pkt[0].offset = 0; + int len = recvfrom(ls->udp.fd, DATA(&pkt[0]), MAXSIZE, 0, &addr[0].sa, &addrlen); +#endif + +#ifdef HAVE_RECVMMSG + if(num < 0) +#else + if(len <= 0 || len > MAXSIZE) +#endif + { if(!sockwouldblock(sockerrno)) logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); return; } - pkt.len = len; - - sockaddrunmap(&addr); /* Some braindead IPv6 implementations do stupid things. */ - - // Try to figure out who sent this packet. - - node_t *n = lookup_node_udp(&addr); - - if(!n) { - // It might be from a 1.1 node, which might have a source ID in the packet. - pkt.offset = 2 * sizeof(node_id_t); - from = lookup_node_id(SRCID(&pkt)); - if(from && !memcmp(DSTID(&pkt), &nullid, sizeof nullid) && from->status.sptps) { - if(sptps_verify_datagram(&from->sptps, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t))) - n = from; - else - goto skip_harder; +#ifndef HAVE_RECVMMSG + pkt[0].len = len; +#endif + + for (i = 0; i < num; i++) + { +#ifdef HAVE_RECVMMSG + pkt[i].len = msg[i].msg_len; + if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) + continue; +#endif + + sockaddrunmap(&addr[i]); /* Some braindead IPv6 implementations do stupid things. */ + + // Try to figure out who sent this packet. + + node_t *n = lookup_node_udp(&addr[i]); + + if(!n) { + // It might be from a 1.1 node, which might have a source ID in the packet. + pkt[i].offset = 2 * sizeof(node_id_t); + from = lookup_node_id(SRCID(&pkt[i])); + if(from && !memcmp(DSTID(&pkt[i]), &nullid, sizeof nullid) && from->status.sptps) { + if(sptps_verify_datagram(&from->sptps, DATA(&pkt[i]), pkt[i].len - 2 * sizeof(node_id_t))) + n = from; + else + goto skip_harder; + } } - } - if(!n) { - pkt.offset = 0; - n = try_harder(&addr, &pkt); - } + if(!n) { + pkt[i].offset = 0; + n = try_harder(&addr[i], &pkt[i]); + } -skip_harder: - if(!n) { - if(debug_level >= DEBUG_PROTOCOL) { - hostname = sockaddr2hostname(&addr); - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); - free(hostname); + skip_harder: + if(!n) { + if(debug_level >= DEBUG_PROTOCOL) { + hostname = sockaddr2hostname(&addr[i]); + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); + free(hostname); + } + continue; } - return; - } - if(n->status.sptps) { - pkt.offset = 2 * sizeof(node_id_t); + if(n->status.sptps) { + pkt[i].offset = 2 * sizeof(node_id_t); - if(!memcmp(DSTID(&pkt), &nullid, sizeof nullid)) { + if(!memcmp(DSTID(&pkt[i]), &nullid, sizeof nullid)) { + direct = true; + from = n; + to = myself; + } else { + from = lookup_node_id(SRCID(&pkt[i])); + to = lookup_node_id(DSTID(&pkt[i])); + } + if(!from || !to) { + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); + continue; + } + + if(to != myself) { + send_sptps_data_priv(to, n, 0, DATA(&pkt[i]), pkt[i].len - 2 * sizeof(node_id_t)); + continue; + } + } else { direct = true; from = n; - to = myself; - } else { - from = lookup_node_id(SRCID(&pkt)); - to = lookup_node_id(DSTID(&pkt)); - } - if(!from || !to) { - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); - return; } - if(to != myself) { - send_sptps_data_priv(to, n, 0, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t)); - return; - } - } else { - direct = true; - from = n; + pkt[i].offset = 0; + if(!receive_udppacket(from, &pkt[i])) + continue; + + n->sock = ls - listen_socket; + if(direct && sockaddrcmp(&addr[i], &n->address)) + update_node_udp(n, &addr[i]); } - - pkt.offset = 0; - if(!receive_udppacket(from, &pkt)) - return; - - n->sock = ls - listen_socket; - if(direct && sockaddrcmp(&addr, &n->address)) - update_node_udp(n, &addr); } void handle_device_data(void *data, int flags) { From dave.taht at gmail.com Wed Dec 2 13:21:56 2015 From: dave.taht at gmail.com (Dave Taht) Date: Wed, 2 Dec 2015 13:21:56 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202115826.GU3025@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> Message-ID: Oh, goodie! I'd made a start on the send direction here: https://github.com/dtaht/tinc/commits/master Perhaps that will help. I would not just pull that as it was just some late night hacking... and it turns out the posix time calls I upgraded to to get better than second resolution are not supported on OSX. My ultimate intent was to move to not bottlenecking or dropping packets on the recv buffer ever (but I figured recvmmsg AND threads would be needed), and move tinc queue management to an fq_codel like system, so as to remove apparent network delays when it was bottlenecked on crypto or output. There are also some notes there on how to do tos encapsulation more right in the upcoming ecn'd world.... and I think I discussed here the prospect of doing a fully fq'd vpn utilizing an entire ipv6 /64.... Dave T?ht Let's go make home routers and wifi faster! With better software! https://www.gofundme.com/savewifi On Wed, Dec 2, 2015 at 12:58 PM, Samuel Thibault wrote: > Hello, > > Linux has a recvmmsg() system call which allows to achieve several > recvfrom() at a time. The patch below makes tinc use it (patch against > 1.1-pre11). Basically the patch turns the handle_incoming_vpn_data > variables into arrays (of size 1 when recvmmsg is not available, and > thus compiled the same as before), and makes the code index into the > arrays. You may want to use interdiff -w /dev/null patch to better see > what changes the patch makes. > > With this patch, I saw the non-ciphered bandwidth achieved over direct > ethernet improve from 680Mbps to 800Mbps (or conversely, reduce the CPU > usage for the same bandwidth). > > More is yet to come: I'll have a look at extending the tun/tap interface > to send/receive several packets at a time, and then also using sendmmsg > will again improve performance. > > Samuel > > --- configure.ac.original 2015-10-02 17:06:31.250034677 +0200 > +++ configure.ac 2015-10-02 17:06:54.147546590 +0200 > @@ -187,7 +187,7 @@ > > dnl Checks for library functions. > AC_TYPE_SIGNAL > -AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], > +AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random recvmmsg select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev], > [], [], [#include "src/have.h"] > ) > > --- src/net_packet.c.original 2015-10-02 16:26:36.828841493 +0200 > +++ src/net_packet.c 2015-10-02 17:15:05.892051503 +0200 > @@ -1057,92 +1057,137 @@ > return n; > } > > +#ifdef HAVE_RECVMMSG > +#define MAX_MSG 256 > +#else > +#define MAX_MSG 1 > +#endif > + > void handle_incoming_vpn_data(void *data, int flags) { > listen_socket_t *ls = data; > - vpn_packet_t pkt; > + vpn_packet_t pkt[MAX_MSG]; > char *hostname; > node_id_t nullid = {}; > - sockaddr_t addr = {}; > - socklen_t addrlen = sizeof addr; > + sockaddr_t addr[MAX_MSG] = {}; > +#ifdef HAVE_RECVMMSG > + struct mmsghdr msg[MAX_MSG]; > + struct iovec iov[MAX_MSG]; > +#else > + socklen_t addrlen = sizeof addr[0]; > +#endif > node_t *from, *to; > bool direct = false; > + int num = 1, i; > > - pkt.offset = 0; > - int len = recvfrom(ls->udp.fd, DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen); > +#ifdef HAVE_RECVMMSG > + for (i = 0; i < MAX_MSG; i++) > + { > + pkt[i].offset = 0; > + msg[i].msg_hdr.msg_name = &addr[i].sa; > + msg[i].msg_hdr.msg_namelen = sizeof(addr[i]); > + iov[i].iov_base = DATA(&pkt[i]); > + iov[i].iov_len = MAXSIZE; > + msg[i].msg_hdr.msg_iov = &iov[i]; > + msg[i].msg_hdr.msg_iovlen = 1; > + msg[i].msg_hdr.msg_control = NULL; > + msg[i].msg_hdr.msg_controllen = 0; > + } > > - if(len <= 0 || len > MAXSIZE) { > + num = recvmmsg(ls->udp.fd, msg, MAX_MSG, MSG_DONTWAIT, NULL); > +#else > + pkt[0].offset = 0; > + int len = recvfrom(ls->udp.fd, DATA(&pkt[0]), MAXSIZE, 0, &addr[0].sa, &addrlen); > +#endif > + > +#ifdef HAVE_RECVMMSG > + if(num < 0) > +#else > + if(len <= 0 || len > MAXSIZE) > +#endif > + { > if(!sockwouldblock(sockerrno)) > logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); > return; > } > > - pkt.len = len; > - > - sockaddrunmap(&addr); /* Some braindead IPv6 implementations do stupid things. */ > - > - // Try to figure out who sent this packet. > - > - node_t *n = lookup_node_udp(&addr); > - > - if(!n) { > - // It might be from a 1.1 node, which might have a source ID in the packet. > - pkt.offset = 2 * sizeof(node_id_t); > - from = lookup_node_id(SRCID(&pkt)); > - if(from && !memcmp(DSTID(&pkt), &nullid, sizeof nullid) && from->status.sptps) { > - if(sptps_verify_datagram(&from->sptps, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t))) > - n = from; > - else > - goto skip_harder; > +#ifndef HAVE_RECVMMSG > + pkt[0].len = len; > +#endif > + > + for (i = 0; i < num; i++) > + { > +#ifdef HAVE_RECVMMSG > + pkt[i].len = msg[i].msg_len; > + if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) > + continue; > +#endif > + > + sockaddrunmap(&addr[i]); /* Some braindead IPv6 implementations do stupid things. */ > + > + // Try to figure out who sent this packet. > + > + node_t *n = lookup_node_udp(&addr[i]); > + > + if(!n) { > + // It might be from a 1.1 node, which might have a source ID in the packet. > + pkt[i].offset = 2 * sizeof(node_id_t); > + from = lookup_node_id(SRCID(&pkt[i])); > + if(from && !memcmp(DSTID(&pkt[i]), &nullid, sizeof nullid) && from->status.sptps) { > + if(sptps_verify_datagram(&from->sptps, DATA(&pkt[i]), pkt[i].len - 2 * sizeof(node_id_t))) > + n = from; > + else > + goto skip_harder; > + } > } > - } > > - if(!n) { > - pkt.offset = 0; > - n = try_harder(&addr, &pkt); > - } > + if(!n) { > + pkt[i].offset = 0; > + n = try_harder(&addr[i], &pkt[i]); > + } > > -skip_harder: > - if(!n) { > - if(debug_level >= DEBUG_PROTOCOL) { > - hostname = sockaddr2hostname(&addr); > - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); > - free(hostname); > + skip_harder: > + if(!n) { > + if(debug_level >= DEBUG_PROTOCOL) { > + hostname = sockaddr2hostname(&addr[i]); > + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname); > + free(hostname); > + } > + continue; > } > - return; > - } > > - if(n->status.sptps) { > - pkt.offset = 2 * sizeof(node_id_t); > + if(n->status.sptps) { > + pkt[i].offset = 2 * sizeof(node_id_t); > > - if(!memcmp(DSTID(&pkt), &nullid, sizeof nullid)) { > + if(!memcmp(DSTID(&pkt[i]), &nullid, sizeof nullid)) { > + direct = true; > + from = n; > + to = myself; > + } else { > + from = lookup_node_id(SRCID(&pkt[i])); > + to = lookup_node_id(DSTID(&pkt[i])); > + } > + if(!from || !to) { > + logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); > + continue; > + } > + > + if(to != myself) { > + send_sptps_data_priv(to, n, 0, DATA(&pkt[i]), pkt[i].len - 2 * sizeof(node_id_t)); > + continue; > + } > + } else { > direct = true; > from = n; > - to = myself; > - } else { > - from = lookup_node_id(SRCID(&pkt)); > - to = lookup_node_id(DSTID(&pkt)); > - } > - if(!from || !to) { > - logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname); > - return; > } > > - if(to != myself) { > - send_sptps_data_priv(to, n, 0, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t)); > - return; > - } > - } else { > - direct = true; > - from = n; > + pkt[i].offset = 0; > + if(!receive_udppacket(from, &pkt[i])) > + continue; > + > + n->sock = ls - listen_socket; > + if(direct && sockaddrcmp(&addr[i], &n->address)) > + update_node_udp(n, &addr[i]); > } > - > - pkt.offset = 0; > - if(!receive_udppacket(from, &pkt)) > - return; > - > - n->sock = ls - listen_socket; > - if(direct && sockaddrcmp(&addr, &n->address)) > - update_node_udp(n, &addr); > } > > void handle_device_data(void *data, int flags) { > > _______________________________________________ > tinc-devel mailing list > tinc-devel at tinc-vpn.org > http://www.tinc-vpn.org/cgi-bin/mailman/listinfo/tinc-devel From samuel.thibault at ens-lyon.org Wed Dec 2 13:36:34 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Wed, 2 Dec 2015 13:36:34 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: References: <20151202115826.GU3025@var.bordeaux.inria.fr> Message-ID: <20151202123634.GB3025@var.bordeaux.inria.fr> Hello, Dave Taht, on Wed 02 Dec 2015 13:21:56 +0100, wrote: > I'd made a start on the send direction here: > https://github.com/dtaht/tinc/commits/master > > Perhaps that will help. Well, converting a sendto call into a sendmsg call is not really "hard" :) What will be really hard is getting multiple packet receive/send over the tap/tun device, because support for it has to be added at the kernel layer first. At least for now we could commit the recvmmsg part? Samuel From guus at tinc-vpn.org Wed Dec 2 13:53:37 2015 From: guus at tinc-vpn.org (Guus Sliepen) Date: Wed, 2 Dec 2015 13:53:37 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202115826.GU3025@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> Message-ID: <20151202125337.GW17506@sliepen.org> On Wed, Dec 02, 2015 at 12:58:26PM +0100, Samuel Thibault wrote: > Linux has a recvmmsg() system call which allows to achieve several > recvfrom() at a time. The patch below makes tinc use it (patch against > 1.1-pre11). Basically the patch turns the handle_incoming_vpn_data > variables into arrays (of size 1 when recvmmsg is not available, and > thus compiled the same as before), and makes the code index into the > arrays. You may want to use interdiff -w /dev/null patch to better see > what changes the patch makes. > > With this patch, I saw the non-ciphered bandwidth achieved over direct > ethernet improve from 680Mbps to 800Mbps (or conversely, reduce the CPU > usage for the same bandwidth). That's great! It would be good though to split handle_incoming_vpn_data() into a function that does the actual recvfrom/mmsg() and one that processes each individual packet, to reduce the level of indentation and make the functions a bit more readable. Then I'll merge it :) I guess in the future, we want to put a "cork" on the output until all packets from a single recvmmsg() have been received, so that we can do sendmmsg() on the resulting outgoing packets. > More is yet to come: I'll have a look at extending the tun/tap interface > to send/receive several packets at a time, and then also using sendmmsg > will again improve performance. Last time I checked, the send/recvmmsg() functionality is actually there in the kernel code, but just not exposed to userspace. It would be great to have access to it though. -- Met vriendelijke groet / with kind regards, Guus Sliepen -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From dave.taht at gmail.com Wed Dec 2 14:13:27 2015 From: dave.taht at gmail.com (Dave Taht) Date: Wed, 2 Dec 2015 14:13:27 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202123634.GB3025@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202123634.GB3025@var.bordeaux.inria.fr> Message-ID: On Wed, Dec 2, 2015 at 1:36 PM, Samuel Thibault wrote: > Hello, > > Dave Taht, on Wed 02 Dec 2015 13:21:56 +0100, wrote: >> I'd made a start on the send direction here: >> https://github.com/dtaht/tinc/commits/master >> >> Perhaps that will help. > > Well, converting a sendto call into a sendmsg call is not really "hard" > :) the "hard" bit was in trying to reliably extract the tos bits and then figure out how to deal with correct ecn encap/decap according to the rfc - ironically, a year ago today. http://www.tinc-vpn.org/pipermail/tinc-devel/2014-December/000680.html but it was only two nights of hacking, then I had to go to something else. The original observation of mine was that we were bottlenecking on the tinc output stage, and dropping at the input stage, with about 30ms latency on the hardware I was trying - where I said AHA! fq_codel in vpnspace might be useful, might scale better to multiple cores, even... and then there was another AHA! when I realized the meshy bits of tinc could be mapped over a received /64 without exposing all that much over a single flow tinc.... making the vpn bits incur nearly zero delay for everything but big flows, and holding the delay down... And after the aha moments, other work took over... getting a generic userspace fq_codel in C done has been on my todo list for a very long time (models exist for ns2, ns3 in c++)... but I'm stuck on finishing up cake, first, and will probably use something derived from that if I ever (or find someone(s) to collaborate with) get a userspace inside of vpn thing back on my plate. > What will be really hard is getting multiple packet receive/send over > the tap/tun device, because support for it has to be added at the kernel > layer first. I think there was some discussion on the netdev list on improving tun/vtap, but I am not sure if that directly went anywhere. More recently Tom Herbert was working on udp encapsulation methods in the kernel "foo over udp" https://www.netdev01.org/docs/herbert-UDP-Encapsulation-Linux.pdf https://lwn.net/Articles/614348/ which preserve things important at high rates like GRO/GSO. > > At least for now we could commit the recvmmsg part? Not my call. It is a linux only thing, so far as I know. > Samuel > _______________________________________________ > tinc-devel mailing list > tinc-devel at tinc-vpn.org > http://www.tinc-vpn.org/cgi-bin/mailman/listinfo/tinc-devel From samuel.thibault at ens-lyon.org Wed Dec 2 14:20:24 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Wed, 2 Dec 2015 14:20:24 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202125337.GW17506@sliepen.org> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> Message-ID: <20151202132024.GA13059@var.bordeaux.inria.fr> Guus Sliepen, on Wed 02 Dec 2015 13:53:37 +0100, wrote: > I guess in the future, we want to put a "cork" on the output until all > packets from a single recvmmsg() have been received, so that we can do > sendmmsg() on the resulting outgoing packets. Yes. > > More is yet to come: I'll have a look at extending the tun/tap interface > > to send/receive several packets at a time, and then also using sendmmsg > > will again improve performance. > > Last time I checked, the send/recvmmsg() functionality is actually there > in the kernel code, but just not exposed to userspace. It would be great > to have access to it though. Well, the tun driver currently expects the writer (for instance) to put one packet at a time. If given more than one packet it's not able to consume only one packet and let the rest for a further call. But it shouldn't be too hard to fix that. Samuel From samuel.thibault at ens-lyon.org Wed Dec 2 14:26:19 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Wed, 2 Dec 2015 14:26:19 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202123634.GB3025@var.bordeaux.inria.fr> Message-ID: <20151202132619.GA14859@var.bordeaux.inria.fr> Dave Taht, on Wed 02 Dec 2015 14:13:27 +0100, wrote: > More recently Tom Herbert was working on udp encapsulation methods in > the kernel "foo over udp" > > https://www.netdev01.org/docs/herbert-UDP-Encapsulation-Linux.pdf > > https://lwn.net/Articles/614348/ > > which preserve things important at high rates like GRO/GSO. Yes, FOU will probably get the highest rates, but it doesn't support even basic encryption, and is harder to set up for normal people :) > > At least for now we could commit the recvmmsg part? > > Not my call. It is a linux only thing, so far as I know. ATM yes. I wouldn't be surprised that other OSes adopt it, though. Samuel From samuel.thibault at ens-lyon.org Wed Dec 2 14:38:37 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Wed, 2 Dec 2015 14:38:37 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202123634.GB3025@var.bordeaux.inria.fr> Message-ID: <20151202133837.GB14859@var.bordeaux.inria.fr> Dave Taht, on Wed 02 Dec 2015 14:13:27 +0100, wrote: > > What will be really hard is getting multiple packet receive/send over > > the tap/tun device, because support for it has to be added at the kernel > > layer first. > > I think there was some discussion on the netdev list on improving > tun/vtap, but I am not sure if that directly went anywhere. I see the patches from Alex Gartrell indeed. It seems things didn't go on. Samuel From dave.taht at gmail.com Wed Dec 2 14:41:35 2015 From: dave.taht at gmail.com (Dave Taht) Date: Wed, 2 Dec 2015 14:41:35 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202132619.GA14859@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202123634.GB3025@var.bordeaux.inria.fr> <20151202132619.GA14859@var.bordeaux.inria.fr> Message-ID: Dave T?ht Let's go make home routers and wifi faster! With better software! https://www.gofundme.com/savewifi On Wed, Dec 2, 2015 at 2:26 PM, Samuel Thibault wrote: > Dave Taht, on Wed 02 Dec 2015 14:13:27 +0100, wrote: >> More recently Tom Herbert was working on udp encapsulation methods in >> the kernel "foo over udp" >> >> https://www.netdev01.org/docs/herbert-UDP-Encapsulation-Linux.pdf >> >> https://lwn.net/Articles/614348/ >> >> which preserve things important at high rates like GRO/GSO. > > Yes, FOU will probably get the highest rates, but it doesn't support > even basic encryption, and is harder to set up for normal people :) I guess my meta point is driven by my headaches. Getting per packet processing to scale up past 100Mbit is hard without offloads even on embedded hardware considered "high end". (I was recently testing the peeling[1] feature of cake[2] only to see it cut performance by over half). Getting ANY modern platform past 10gbit is *really* hard. [3] So while recvmmsg and optimizations like that are needed, some harder thinking about the other brick walls coming up would be helpful.. (which is why I stopped) >> > At least for now we could commit the recvmmsg part? >> >> Not my call. It is a linux only thing, so far as I know. > > ATM yes. I wouldn't be surprised that other OSes adopt it, though. Given how slow other OSes are evolving, I would not hold my breath, and retain code paths that worked with them. [1] https://lists.bufferbloat.net/pipermail/cake/2015-November/000846.html [2] http://www.bufferbloat.net/projects/codel/wiki/CakeTechnical [3] http://netoptimizer.blogspot.se/2014/10/unlocked-10gbps-tx-wirespeed-smallest.html From samuel.thibault at ens-lyon.org Wed Dec 2 14:48:22 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Wed, 2 Dec 2015 14:48:22 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202123634.GB3025@var.bordeaux.inria.fr> <20151202132619.GA14859@var.bordeaux.inria.fr> Message-ID: <20151202134822.GJ3025@var.bordeaux.inria.fr> Dave Taht, on Wed 02 Dec 2015 14:41:35 +0100, wrote: > I guess my meta point is driven by my headaches. Getting per packet > processing to scale up past 100Mbit is hard without offloads even on > embedded hardware considered "high end". In my tests I was getting 800Mbps with common laptop Gb ethernet devices. > >> > At least for now we could commit the recvmmsg part? > >> > >> Not my call. It is a linux only thing, so far as I know. > > > > ATM yes. I wouldn't be surprised that other OSes adopt it, though. > > Given how slow other OSes are evolving, I would not hold my breath, > and retain code paths that worked with them. Sure! Samuel From dave.taht at gmail.com Wed Dec 2 15:01:16 2015 From: dave.taht at gmail.com (Dave Taht) Date: Wed, 2 Dec 2015 15:01:16 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202134822.GJ3025@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202123634.GB3025@var.bordeaux.inria.fr> <20151202132619.GA14859@var.bordeaux.inria.fr> <20151202134822.GJ3025@var.bordeaux.inria.fr> Message-ID: On Wed, Dec 2, 2015 at 2:48 PM, Samuel Thibault wrote: > Dave Taht, on Wed 02 Dec 2015 14:41:35 +0100, wrote: >> I guess my meta point is driven by my headaches. Getting per packet >> processing to scale up past 100Mbit is hard without offloads even on >> embedded hardware considered "high end". > > In my tests I was getting 800Mbps with common laptop Gb ethernet > devices. yep. what you are doing is a worthwhile improvement. But it isn't line rate, even on a modern laptop... I also try to get people measuring latency and bidirectional throughput also - give the flent tool a shot- it has a great gui, gives you all sorts of nice graphs and lets you create a variety of useful workloads. https://flent.org/ The best part for me is the ability to make a change in something, run a test or string of tests, and plot the results in comparison with the prior changes. the rrul test is about the most common one used these days, although things like tcp_upload_100 are good tests of small packets in one direction or another. example of rrul: http://burntchrome.blogspot.se/2014/05/fixing-bufferbloat-on-comcasts-blast.html Example of iterating over a set of changes to napi and BQL to get better performance http://snapon.cs.kau.se/~d/beagle_bql/beaglebonewithbql.png *love flent*. > >> >> > At least for now we could commit the recvmmsg part? >> >> >> >> Not my call. It is a linux only thing, so far as I know. >> > >> > ATM yes. I wouldn't be surprised that other OSes adopt it, though. >> >> Given how slow other OSes are evolving, I would not hold my breath, >> and retain code paths that worked with them. > > Sure! > > Samuel From etienne at edechamps.fr Wed Dec 2 22:07:41 2015 From: etienne at edechamps.fr (Etienne Dechamps) Date: Wed, 2 Dec 2015 21:07:41 +0000 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202132024.GA13059@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151202132024.GA13059@var.bordeaux.inria.fr> Message-ID: On 2 December 2015 at 13:20, Samuel Thibault wrote: >> > More is yet to come: I'll have a look at extending the tun/tap interface >> > to send/receive several packets at a time, and then also using sendmmsg >> > will again improve performance. >> >> Last time I checked, the send/recvmmsg() functionality is actually there >> in the kernel code, but just not exposed to userspace. It would be great >> to have access to it though. > > Well, the tun driver currently expects the writer (for instance) to > put one packet at a time. If given more than one packet it's not able > to consume only one packet and let the rest for a further call. But it > shouldn't be too hard to fix that. It sounds like you would be interested in section 3.3 "Multiqueue tuntap interface" of https://www.kernel.org/doc/Documentation/networking/tuntap.txt Overall, I find your findings quite interesting. IMHO, the ideal way to increase raw tinc performance would be to make the most CPU and system call intensive parts of tinc's TX and RX paths (mostly sockets, TUN/TAP, and crypto) multi-threaded - that would make it way more scalable in terms of throughput, and it would also benefit pretty much any OS (as opposed to making Linux-specific optimizations). However, that's a much bigger can of worms as the current codebase very strongly assumes single-threaded operation, so it would likely require a lot of work. Another possible avenue for increasing performance would be to make use of some of the highly optimized ASM versions of ChaCha-Poly1305 (possibly through the use of some crypto library) instead of the simple C implementation that tinc-1.1 currently uses. According to benchmark results there is quite a lot to be gained: http://bench.cr.yp.to/impl-stream/chacha20.html From samuel.thibault at ens-lyon.org Thu Dec 10 01:35:41 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Thu, 10 Dec 2015 01:35:41 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151202125337.GW17506@sliepen.org> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> Message-ID: <20151210003541.GV3521@var.home> Hello, Guus Sliepen, on Wed 02 Dec 2015 13:53:37 +0100, wrote: > That's great! It would be good though to split > handle_incoming_vpn_data() into a function that does the actual > recvfrom/mmsg() and one that processes each individual packet, to reduce > the level of indentation and make the functions a bit more readable. > Then I'll merge it :) Here it is. Samuel -------------- next part -------------- diff --git a/configure.ac b/configure.ac index 5cdd642..fcac9d2 100644 --- a/configure.ac +++ b/configure.ac @@ -187,7 +187,7 @@ AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp, dnl Checks for library functions. AC_TYPE_SIGNAL -AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall pselect putenv random select strdup strerror strsignal strtol system unsetenv usleep vsyslog writev], +AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall pselect putenv random recvmmsg select strdup strerror strsignal strtol system unsetenv usleep vsyslog writev], [], [], [#include "src/have.h"] ) diff --git a/src/net_packet.c b/src/net_packet.c index e67857c..174db34 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -695,31 +695,26 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { return n; } -void handle_incoming_vpn_data(int sock) { - vpn_packet_t pkt; +#ifdef HAVE_RECVMMSG +#define MAX_MSG 256 +#else +#define MAX_MSG 1 +#endif + +static void handle_incoming_vpn_packet(int sock, vpn_packet_t *pkt, sockaddr_t *from) { char *hostname; - sockaddr_t from; - socklen_t fromlen = sizeof(from); node_t *n; - pkt.len = recvfrom(listen_socket[sock].udp, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); - - if(pkt.len < 0) { - if(!sockwouldblock(sockerrno)) - logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); - return; - } - - sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ + sockaddrunmap(from); /* Some braindead IPv6 implementations do stupid things. */ - n = lookup_node_udp(&from); + n = lookup_node_udp(from); if(!n) { - n = try_harder(&from, &pkt); + n = try_harder(from, pkt); if(n) - update_node_udp(n, &from); + update_node_udp(n, from); else ifdebug(PROTOCOL) { - hostname = sockaddr2hostname(&from); + hostname = sockaddr2hostname(from); logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname); free(hostname); return; @@ -730,5 +725,55 @@ void handle_incoming_vpn_data(int sock) { n->sock = sock; - receive_udppacket(n, &pkt); + receive_udppacket(n, pkt); +} + +void handle_incoming_vpn_data(int sock) { + vpn_packet_t pkt[MAX_MSG]; + sockaddr_t from[MAX_MSG]; +#ifdef HAVE_RECVMMSG + struct mmsghdr msg[MAX_MSG]; + struct iovec iov[MAX_MSG]; +#else + socklen_t fromlen = sizeof(from[0]); +#endif + int num = 1, i; + +#ifdef HAVE_RECVMMSG + for(i = 0; i < MAX_MSG; i++) + { + msg[i].msg_hdr.msg_name = &from[i].sa; + msg[i].msg_hdr.msg_namelen = sizeof(from[i]); + iov[i].iov_base = &pkt[i].seqno; + iov[i].iov_len = MAXSIZE; + msg[i].msg_hdr.msg_iov = &iov[i]; + msg[i].msg_hdr.msg_iovlen = 1; + msg[i].msg_hdr.msg_control = NULL; + msg[i].msg_hdr.msg_controllen = 0; + } + num = recvmmsg(listen_socket[sock].udp, msg, MAX_MSG, MSG_DONTWAIT, NULL); +#else + pkt[0].len = recvfrom(listen_socket[sock].udp, (char *) &pkt[0].seqno, MAXSIZE, 0, &from[0].sa, &fromlen); +#endif + +#ifdef HAVE_RECVMMSG + if(num < 0) +#else + if(pkt[0].len < 0) +#endif + { + if(!sockwouldblock(sockerrno)) + logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + return; + } + + for(i = 0; i < num; i++) + { +#ifdef HAVE_RECVMMSG + pkt[i].len = msg[i].msg_len; + if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) + continue; +#endif + handle_incoming_vpn_packet(sock, &pkt[i], &from[i]); + } } From mjt at tls.msk.ru Thu Dec 10 07:20:26 2015 From: mjt at tls.msk.ru (Michael Tokarev) Date: Thu, 10 Dec 2015 09:20:26 +0300 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151210003541.GV3521@var.home> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> Message-ID: <566919AA.2010306@msgid.tls.msk.ru> 10.12.2015 03:35, Samuel Thibault wrote: [] I suggest reducing ifdeffery in handle_incoming_vpn_data(), especially the error checking code. The function isn't that large now, it might be much better to have two different implementations. Like this (untested, patch attached): void handle_incoming_vpn_data(int sock) { #ifdef HAVE_RECVMMSG #define MAX_MSG 256 vpn_packet_t pkt[MAX_MSG]; sockaddr_t from[MAX_MSG]; struct mmsghdr msg[MAX_MSG]; struct iovec iov[MAX_MSG]; int num = 1, i; for(i = 0; i < MAX_MSG; i++) { msg[i].msg_hdr.msg_name = &from[i].sa; msg[i].msg_hdr.msg_namelen = sizeof(from[i]); iov[i].iov_base = &pkt[i].seqno; iov[i].iov_len = MAXSIZE; msg[i].msg_hdr.msg_iov = &iov[i]; msg[i].msg_hdr.msg_iovlen = 1; msg[i].msg_hdr.msg_control = NULL; msg[i].msg_hdr.msg_controllen = 0; } num = recvmmsg(listen_socket[sock].udp, msg, MAX_MSG, MSG_DONTWAIT, NULL); if(num < 0) { if(!sockwouldblock(sockerrno)) logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); return; } for(i = 0; i < num; i++) { pkt[i].len = msg[i].msg_len; if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE) continue; handle_incoming_vpn_packet(sock, &pkt[i], &from[i]); } #else vpn_packet_t pkt; sockaddr_t from; socklen_t fromlen = sizeof(from); pkt.len = recvfrom(listen_socket[sock].udp, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); if(pkt.len < 0) { if(!sockwouldblock(sockerrno)) logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); return; } handle_incoming_vpn_packet(sock, &pkt, &from); #endif } /mjt -------------- next part -------------- A non-text attachment was scrubbed... Name: mrecv.patch Type: text/x-patch Size: 2858 bytes Desc: not available URL: From mjt at tls.msk.ru Thu Dec 10 07:34:45 2015 From: mjt at tls.msk.ru (Michael Tokarev) Date: Thu, 10 Dec 2015 09:34:45 +0300 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <566919AA.2010306@msgid.tls.msk.ru> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> Message-ID: <56691D05.2070901@msgid.tls.msk.ru> 10.12.2015 09:20, Michael Tokarev wrote: > 10.12.2015 03:35, Samuel Thibault wrote: > [] > > I suggest reducing ifdeffery in handle_incoming_vpn_data(), especially > the error checking code. > > The function isn't that large now, it might be much better to have > two different implementations. Like this (untested, patch attached): > > void handle_incoming_vpn_data(int sock) { > > #ifdef HAVE_RECVMMSG > #define MAX_MSG 256 > > vpn_packet_t pkt[MAX_MSG]; > sockaddr_t from[MAX_MSG]; > struct mmsghdr msg[MAX_MSG]; > struct iovec iov[MAX_MSG]; > int num = 1, i; > > for(i = 0; i < MAX_MSG; i++) > { > msg[i].msg_hdr.msg_name = &from[i].sa; > msg[i].msg_hdr.msg_namelen = sizeof(from[i]); > iov[i].iov_base = &pkt[i].seqno; > iov[i].iov_len = MAXSIZE; > msg[i].msg_hdr.msg_iov = &iov[i]; > msg[i].msg_hdr.msg_iovlen = 1; > msg[i].msg_hdr.msg_control = NULL; > msg[i].msg_hdr.msg_controllen = 0; > } Also, this is interesting. We should either reduce MAX_MSG to, say, 64, or even 16, and/or initialize this array statically (except of iov.iov_len). There's just too much work doing on each step, and it is highly unlikely we'll have 256 packets in queue to process. Thanks, /mjt From guus at tinc-vpn.org Thu Dec 10 09:10:07 2015 From: guus at tinc-vpn.org (Guus Sliepen) Date: Thu, 10 Dec 2015 09:10:07 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <56691D05.2070901@msgid.tls.msk.ru> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> <56691D05.2070901@msgid.tls.msk.ru> Message-ID: <20151210081007.GB17506@sliepen.org> On Thu, Dec 10, 2015 at 09:34:45AM +0300, Michael Tokarev wrote: > > 10.12.2015 03:35, Samuel Thibault wrote: > > Here it is. Thanks! > 10.12.2015 09:20, Michael Tokarev wrote: > > > > I suggest reducing ifdeffery in handle_incoming_vpn_data(), especially > > the error checking code. That does seem to make it even more readable. I can merge both your changes :) > Also, this is interesting. We should either reduce MAX_MSG to, say, 64, > or even 16, and/or initialize this array statically (except of iov.iov_len). Reducing MAX_MSG might make sense. I think some real-world testing should tell us how many packets are queued on average under high load, and size the arrays accordingly. As for static initialization, I don't see that being helpful. It would be much more verbose to write out the initialization of a whole array, and the compiler would generate more or less identical code to the for-loop in Samuel's patch. The only improvement I can think of is this: for(i = 0; i < MAX_MSG; i++) { iov[i] = (struct iovec){ .iov_base = &pkt[i].seqno; .iov_len = MAXSIZE; }; msg[i].msg_hdr = (struct msg_hdr){ .msg_name = &from[i].sa, .msg_namelen = sizeof from[i], .msg_iov = &iov[i], msg_iovlen = 1, }; } Or am I missing something? -- Met vriendelijke groet / with kind regards, Guus Sliepen -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From samuel.thibault at ens-lyon.org Thu Dec 10 10:15:19 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Thu, 10 Dec 2015 10:15:19 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <56691D05.2070901@msgid.tls.msk.ru> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> <56691D05.2070901@msgid.tls.msk.ru> Message-ID: <20151210091519.GA2963@var.bordeaux.inria.fr> Michael Tokarev, on Thu 10 Dec 2015 09:34:45 +0300, wrote: > it is highly unlikely we'll have 256 packets in queue to process. I did get a bit more than a hundred packets in the queue at 800Mbps. But we can reduce to 64, yes. I wouldn't recommend using a static buffer, since we'd want to go threaded at some point. Allocating an array on the stack is very cheap anyway. Samuel From guus at tinc-vpn.org Thu Dec 10 16:53:14 2015 From: guus at tinc-vpn.org (Guus Sliepen) Date: Thu, 10 Dec 2015 16:53:14 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151210091519.GA2963@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> <56691D05.2070901@msgid.tls.msk.ru> <20151210091519.GA2963@var.bordeaux.inria.fr> Message-ID: <20151210155314.GD17506@sliepen.org> On Thu, Dec 10, 2015 at 10:15:19AM +0100, Samuel Thibault wrote: > I did get a bit more than a hundred packets in the queue at 800Mbps. But > we can reduce to 64, yes. I wouldn't recommend using a static buffer, > since we'd want to go threaded at some point. Allocating an array on the > stack is very cheap anyway. I assumed that one would only get more than 1 packet at a time under heavy load, but apparently traffic is bursty enough that it even triggers in a simple SSH session. But it rarely is over 64, so I kept it at that. Your patch was apparently against 1.0.26, not 1.1pre11 as you said earlier, so I had to port it to the 1.1 branch. It's committed now, with Michael's de-ifdeffication incorporated as well. I also made the buffers static, as suggested by Michael. If we go the multi-threaded way, they can be made thread-local. -- Met vriendelijke groet / with kind regards, Guus Sliepen -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From samuel.thibault at ens-lyon.org Thu Dec 10 17:40:17 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Thu, 10 Dec 2015 17:40:17 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151210155314.GD17506@sliepen.org> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> <56691D05.2070901@msgid.tls.msk.ru> <20151210091519.GA2963@var.bordeaux.inria.fr> <20151210155314.GD17506@sliepen.org> Message-ID: <20151210164017.GE2963@var.bordeaux.inria.fr> Guus Sliepen, on Thu 10 Dec 2015 16:53:14 +0100, wrote: > Your patch was apparently against 1.0.26, Urgll... I took git to get the latest code, and assumed that the latest commit there being 6th november, it was the latest code... Is there a reason why the master branch is not the trunk? This is really surprising for any contributor. > not 1.1pre11 as you said earlier, My earlier patch was really against 1.1pre11. My latest patch was a port of it to the git master, thinking it was the latest code... Samuel From guus at tinc-vpn.org Thu Dec 10 18:33:09 2015 From: guus at tinc-vpn.org (Guus Sliepen) Date: Thu, 10 Dec 2015 18:33:09 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151210164017.GE2963@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> <56691D05.2070901@msgid.tls.msk.ru> <20151210091519.GA2963@var.bordeaux.inria.fr> <20151210155314.GD17506@sliepen.org> <20151210164017.GE2963@var.bordeaux.inria.fr> Message-ID: <20151210173309.GP23648@sliepen.org> On Thu, Dec 10, 2015 at 05:40:17PM +0100, Samuel Thibault wrote: > Urgll... I took git to get the latest code, and assumed that the > latest commit there being 6th november, it was the latest code... Is > there a reason why the master branch is not the trunk? This is really > surprising for any contributor. It is a bit unfortunate, but now we're stuck with it. > My earlier patch was really against 1.1pre11. My latest patch was a > port of it to the git master, thinking it was the latest code... No problem. Now you know for when you're working on the sendmmsg() part :) -- Met vriendelijke groet / with kind regards, Guus Sliepen -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From samuel.thibault at ens-lyon.org Thu Dec 10 18:39:47 2015 From: samuel.thibault at ens-lyon.org (Samuel Thibault) Date: Thu, 10 Dec 2015 18:39:47 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151210173309.GP23648@sliepen.org> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> <56691D05.2070901@msgid.tls.msk.ru> <20151210091519.GA2963@var.bordeaux.inria.fr> <20151210155314.GD17506@sliepen.org> <20151210164017.GE2963@var.bordeaux.inria.fr> <20151210173309.GP23648@sliepen.org> Message-ID: <20151210173947.GZ2963@var.bordeaux.inria.fr> Guus Sliepen, on Thu 10 Dec 2015 18:33:09 +0100, wrote: > On Thu, Dec 10, 2015 at 05:40:17PM +0100, Samuel Thibault wrote: > > Urgll... I took git to get the latest code, and assumed that the > > latest commit there being 6th november, it was the latest code... Is > > there a reason why the master branch is not the trunk? This is really > > surprising for any contributor. > > It is a bit unfortunate, but now we're stuck with it. Why? Is it used for something? One can force an update, effectively dropping the existing spurious commits. Samuel From guus at tinc-vpn.org Thu Dec 10 18:49:23 2015 From: guus at tinc-vpn.org (Guus Sliepen) Date: Thu, 10 Dec 2015 18:49:23 +0100 Subject: [PATCH] Receive multiple packets at a time In-Reply-To: <20151210173947.GZ2963@var.bordeaux.inria.fr> References: <20151202115826.GU3025@var.bordeaux.inria.fr> <20151202125337.GW17506@sliepen.org> <20151210003541.GV3521@var.home> <566919AA.2010306@msgid.tls.msk.ru> <56691D05.2070901@msgid.tls.msk.ru> <20151210091519.GA2963@var.bordeaux.inria.fr> <20151210155314.GD17506@sliepen.org> <20151210164017.GE2963@var.bordeaux.inria.fr> <20151210173309.GP23648@sliepen.org> <20151210173947.GZ2963@var.bordeaux.inria.fr> Message-ID: <20151210174923.GQ23648@sliepen.org> On Thu, Dec 10, 2015 at 06:39:47PM +0100, Samuel Thibault wrote: > Guus Sliepen, on Thu 10 Dec 2015 18:33:09 +0100, wrote: > > On Thu, Dec 10, 2015 at 05:40:17PM +0100, Samuel Thibault wrote: > > > Urgll... I took git to get the latest code, and assumed that the > > > latest commit there being 6th november, it was the latest code... Is > > > there a reason why the master branch is not the trunk? This is really > > > surprising for any contributor. > > > > It is a bit unfortunate, but now we're stuck with it. > > Why? Is it used for something? One can force an update, effectively > dropping the existing spurious commits. It's used for the 1.0 branch, which still gets updates now and then. Since there are other people who cloned/forked the git repository and may want to sync, I won't change the master branch (yet). -- Met vriendelijke groet / with kind regards, Guus Sliepen -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: