diff --git a/ww/tundevice/tun.h b/ww/tundevice/tun.h index f8303c3..fb1b3a5 100644 --- a/ww/tundevice/tun.h +++ b/ww/tundevice/tun.h @@ -1,9 +1,9 @@ #pragma once #include "buffer_pool.h" -#include "master_pool.h" #include "hloop.h" #include "hplatform.h" #include "hthread.h" +#include "master_pool.h" #include #define TUN_LOG_EVERYTHING true @@ -22,22 +22,30 @@ typedef struct tun_device_s { char *name; // hio_t *io; not using fd multiplexer - tun_handle_t handle; - hthread_t readThread; - hthread_t writeThread; - hthread_routine routine_reader; - hthread_routine routine_writer; + tun_handle_t handle; + void *userdata; + hthread_t read_thread; + hthread_t write_thread; + + hthread_routine routine_reader; + hthread_routine routine_writer; + master_pool_t *reader_message_pool; generic_pool_t *reader_shift_buffer_pool; buffer_pool_t *reader_buffer_pool; - struct hchan_s *writer_buffer_channel; TunReadEventHandle read_event_callback; - void *userdata; - atomic_bool running; - atomic_bool up; + + struct hchan_s *writer_buffer_channel; + atomic_bool running; + atomic_bool up; } tun_device_t; tun_device_t *createTunDevice(const char *name, bool offload, void *userdata, TunReadEventHandle cb); -void bringTunDeviceUP(tun_device_t *tdev); -void writeToTunDevce(tun_device_t *tdev, shift_buffer_t *buf); + +bool bringTunDeviceUP(tun_device_t *tdev); +bool bringTunDeviceDown(tun_device_t *tdev); +bool assignIpToTunDevice(tun_device_t *tdev, const char *ip_presentation, int subnet); +bool unAssignIpToTunDevice(tun_device_t *tdev, const char *ip_presentation, int subnet); + +void writeToTunDevce(tun_device_t *tdev, shift_buffer_t *buf); diff --git a/ww/tundevice/tun_linux.c b/ww/tundevice/tun_linux.c index e8e3319..d88eb3a 100644 --- a/ww/tundevice/tun_linux.c +++ b/ww/tundevice/tun_linux.c @@ -2,6 +2,7 @@ #include "hchan.h" #include "loggers/network_logger.h" #include "tun.h" +#include "utils/procutils.h" #include "ww.h" #include #include @@ -16,8 +17,9 @@ enum { - kReadPacketSize = 1500, - kMasterMessagePoolCap = 64 + kReadPacketSize = 1500, + kMasterMessagePoolCap = 64, + kTunWriteChannelQueueMax = 128 }; struct msg_event @@ -26,7 +28,7 @@ struct msg_event shift_buffer_t *buf; }; -static void printPacketInfo(const unsigned char *buffer, int length) +static void printIPPacketInfo(const char *devname, const unsigned char *buffer) { struct iphdr *ip_header = (struct iphdr *) buffer; char src_ip[INET_ADDRSTRLEN]; @@ -35,12 +37,19 @@ static void printPacketInfo(const unsigned char *buffer, int length) inet_ntop(AF_INET, &ip_header->saddr, src_ip, INET_ADDRSTRLEN); inet_ntop(AF_INET, &ip_header->daddr, dst_ip, INET_ADDRSTRLEN); - printf("From %s to %s, Data: ", src_ip, dst_ip); - for (int i = sizeof(struct iphdr); i < length; i++) + char logbuf[128]; + int rem = sizeof(logbuf); + char *ptr = logbuf; + int ret = snprintf(ptr, rem, "TunDevice: %s => From %s to %s, Data:", devname, src_ip, dst_ip); + ptr += ret; + rem -= ret; + for (int i = sizeof(struct iphdr); i < 10; i++) { - printf("%02x ", buffer[i]); + ret = snprintf(ptr, rem, "%02x ", buffer[i]); + ptr += ret; + rem -= ret; } - printf("\n"); + LOGD(logbuf); } static pool_item_t *allocTunMsgPoolHandle(struct master_pool_s *pool, void *userdata) @@ -98,13 +107,14 @@ static HTHREAD_ROUTINE(routineReadFromTun) // NOLINT if (nread < 0) { - LOGF("TunDevice: Reading from TUN device failed"); - exit(1); + LOGE("TunDevice: reading from TUN device failed"); + reuseBuffer(tdev->reader_buffer_pool, buf); + return 0; } if (TUN_LOG_EVERYTHING) { - LOGD("TunDevice: Read %zd bytes from device %s\n", nread, tdev->name); + LOGD("TunDevice: read %zd bytes from device %s", nread, tdev->name); } distributePacketPayload(tdev, distribute_tid++, buf); @@ -127,14 +137,76 @@ static HTHREAD_ROUTINE(routineWriteToTun) // NOLINT return 0; } -void bringTunDeviceUP(tun_device_t *tdev) +bool unAssignIpToTunDevice(tun_device_t *tdev, const char *ip_presentation, int subnet) +{ + char command[128]; + + snprintf(command, sizeof(command), "ip addr del %s/%d dev %s", ip_presentation, subnet, tdev->name); + if (execCmd(command).exit_code != 0) + { + LOGE("TunDevice: error unassigning ip address"); + return false; + } + LOGD("TunDevice: ip address removed from %s", tdev->name); + return true; +} + +bool assignIpToTunDevice(tun_device_t *tdev, const char *ip_presentation, int subnet) +{ + char command[128]; + + snprintf(command, sizeof(command), "ip addr add %s/%d dev %s", ip_presentation, subnet, tdev->name); + if (execCmd(command).exit_code != 0) + { + LOGF("TunDevice: error setting ip address"); + return false; + } + LOGD("TunDevice: ip address %s/%d assigned to dev %s", ip_presentation, subnet, tdev->name); + return true; +} + +bool bringTunDeviceUP(tun_device_t *tdev) { assert(! tdev->up); tdev->up = true; tdev->running = true; - hthread_create(tdev->routine_reader, tdev); - hthread_create(tdev->routine_writer, tdev); + + char command[128]; + snprintf(command, sizeof(command), "ip link set dev %s up", tdev->name); + if (execCmd(command).exit_code != 0) + { + LOGF("TunDevice: error bringing device %s up", tdev->name); + return false; + } + LOGD("TunDevice: device %s is now up", tdev->name); + + tdev->read_thread = hthread_create(tdev->routine_reader, tdev); + tdev->write_thread = hthread_create(tdev->routine_writer, tdev); + return true; +} + +bool bringTunDeviceDown(tun_device_t *tdev) +{ + assert(tdev->up); + + tdev->running = false; + tdev->up = false; + + char command[128]; + + snprintf(command, sizeof(command), "ip link set dev %s down", tdev->name); + if (execCmd(command).exit_code != 0) + { + LOGF("TunDevice: error bringing %s down", tdev->name); + return false; + } + LOGD("TunDevice: device %s is now down", tdev->name); + + hchan_Close(tdev->writer_buffer_channel); + hthread_join(tdev->read_thread); + hthread_join(tdev->write_thread); + return true; } tun_device_t *createTunDevice(const char *name, bool offload, void *userdata, TunReadEventHandle cb) @@ -168,6 +240,7 @@ tun_device_t *createTunDevice(const char *name, bool offload, void *userdata, Tu generic_pool_t *sb_pool = newGenericPoolWithCap(GSTATE.masterpool_shift_buffer_pools, (64) + GSTATE.ram_profile, allocShiftBufferPoolHandle, destroyShiftBufferPoolHandle); + buffer_pool_t *bpool = createBufferPool(NULL, GSTATE.masterpool_buffer_pools_small, sb_pool); tun_device_t *tdev = globalMalloc(sizeof(tun_device_t)); @@ -178,10 +251,9 @@ tun_device_t *createTunDevice(const char *name, bool offload, void *userdata, Tu .reader_shift_buffer_pool = sb_pool, .read_event_callback = cb, .userdata = userdata, + .writer_buffer_channel = hchan_Open(sizeof(void *), kTunWriteChannelQueueMax), .reader_message_pool = newMasterPoolWithCap(kMasterMessagePoolCap), - .reader_buffer_pool = createBufferPool(NULL, GSTATE.masterpool_buffer_pools_small, sb_pool) - - }; + .reader_buffer_pool = bpool}; installMasterPoolAllocCallbacks(tdev->reader_message_pool, tdev, allocTunMsgPoolHandle, destroyTunMsgPoolHandle);