From 95f09569beb2e304e6a2112d20cee6fab88f3729 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 8 Apr 2017 13:34:40 +0200 Subject: [PATCH] Use getmsg()/putmsg() instead of read()/write() on Solaris. This fixes a problem where read() returns packets from the IP layer before fragmentation is done. # Conflicts: # src/solaris/device.c --- src/solaris/device.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/solaris/device.c b/src/solaris/device.c index 53d3d63c..89481c7b 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -24,6 +24,7 @@ #include #include +#include #include "../conf.h" #include "../device.h" @@ -296,11 +297,16 @@ static void close_device(void) { } static bool read_packet(vpn_packet_t *packet) { - int inlen; + int result; + struct strbuf sbuf; + int f = 0; switch(device_type) { case DEVICE_TYPE_TUN: - if((inlen = read(device_fd, DATA(packet) + 14, MTU - 14)) <= 0) { + sbuf.maxlen = MTU - 14; + sbuf.buf = (char *)DATA(packet) + 14; + + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } @@ -320,16 +326,19 @@ static bool read_packet(vpn_packet_t *packet) { } memset(DATA(packet), 0, 12); - packet->len = inlen + 14; + packet->len = sbuf.len + 14; break; case DEVICE_TYPE_TAP: - if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); + sbuf.maxlen = MTU; + sbuf.buf = (char *)DATA(packet); + + if((result = getmsg(device_fd, NULL, &sbuf, &f)) < 0) { + logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno)); return false; } - packet->len = inlen + 14; + packet->len = sbuf.len; break; default: @@ -344,17 +353,25 @@ static bool read_packet(vpn_packet_t *packet) { static bool write_packet(vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", packet->len, device_info); + struct strbuf sbuf; + switch(device_type) { case DEVICE_TYPE_TUN: - if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + sbuf.len = packet->len - 14; + sbuf.buf = (char *)DATA(packet) + 14; + + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break; case DEVICE_TYPE_TAP: - if(write(device_fd, DATA(packet), packet->len) < 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); + sbuf.len = packet->len; + sbuf.buf = (char *)DATA(packet); + + if(putmsg(device_fd, NULL, &sbuf, 0) < 0) { + logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno)); return false; } break;