From 8b03965912d3a3070c4e447c65b70a7c16067ee2 Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Fri, 16 Oct 2015 19:30:01 -0400 Subject: [PATCH] Added status debugs --- netcon/Intercept.c | 12 ++++++++---- netcon/NetconEthernetTap.cpp | 26 +++++++++++++++++--------- netcon/libintercept.so.1.0 | Bin 45992 -> 45888 bytes 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/netcon/Intercept.c b/netcon/Intercept.c index c53c10156..d431f8251 100755 --- a/netcon/Intercept.c +++ b/netcon/Intercept.c @@ -496,10 +496,9 @@ int connect(CONNECT_SIG) //int flags = fcntl(__fd, F_GETFD); //dwr("connect(): socket flags = %d\n", flags); - - if(sock_type && O_NONBLOCK) { - dwr("connect(): O_NONBLOCK\n"); - } + //if(sock_type && O_NONBLOCK) { + // dwr("connect(): O_NONBLOCK\n"); + //} /* assemble and route command */ int err; @@ -656,6 +655,11 @@ int accept(ACCEPT_SIG) errno = EMFILE; return -1; } + /* Check address length */ + if(addrlen < 0) { + errno = EINVAL; + return -1; + } #endif /* make sure we don't touch any standard outputs */ diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp index 003e0b66e..a5ce6f805 100644 --- a/netcon/NetconEthernetTap.cpp +++ b/netcon/NetconEthernetTap.cpp @@ -51,6 +51,7 @@ #define APPLICATION_POLL_FREQ 1 #define ZT_LWIP_TCP_TIMER_INTERVAL 10 +#define STATUS_TMR_INTERVAL 1000 namespace ZeroTier { @@ -317,9 +318,8 @@ void NetconEthernetTap::threadMain() { fprintf(stderr, "_threadMain()\n"); uint64_t prev_tcp_time = 0; + uint64_t prev_status_time = 0; uint64_t prev_etharp_time = 0; -fprintf(stderr, "- TCP_SND_QUEUELEN = %d\n", TCP_SND_QUEUELEN); -fprintf(stderr, "- TCP_MAXRTX = %d\n", TCP_MAXRTX); /* fprintf(stderr, "- MEM_SIZE = %dM\n", MEM_SIZE / (1024*1024)); @@ -329,7 +329,8 @@ fprintf(stderr, "- TCP_MAXRTX = %d\n", TCP_MAXRTX); fprintf(stderr, "- MEMP_NUM_TCP_PCB_LISTEN = %d\n", MEMP_NUM_TCP_PCB_LISTEN); fprintf(stderr, "- MEMP_NUM_TCP_SEG = %d\n", MEMP_NUM_TCP_SEG); fprintf(stderr, "- PBUF_POOL_SIZE = %d\n", PBUF_POOL_SIZE); - + fprintf(stderr, "- TCP_SND_QUEUELEN = %d\n", TCP_SND_QUEUELEN); + fprintf(stderr, "- TCP_MAXRTX = %d\n", TCP_MAXRTX); fprintf(stderr, "- IP_REASSEMBLY = %d\n", IP_REASSEMBLY); fprintf(stderr, "- TCP_WND = %d\n", TCP_WND); fprintf(stderr, "- TCP_MSS = %d\n", TCP_MSS); @@ -340,14 +341,20 @@ fprintf(stderr, "- TCP_MAXRTX = %d\n", TCP_MAXRTX); // Main timer loop while (_run) { + uint64_t now = OSUtils::now(); uint64_t since_tcp = now - prev_tcp_time; uint64_t since_etharp = now - prev_etharp_time; - + uint64_t since_status = now - prev_status_time; uint64_t tcp_remaining = ZT_LWIP_TCP_TIMER_INTERVAL; uint64_t etharp_remaining = ARP_TMR_INTERVAL; + uint64_t status_remaining = STATUS_TMR_INTERVAL; + if (since_status >= STATUS_TMR_INTERVAL) { + prev_status_time = now; + fprintf(stderr, "tcp_conns = %d, rpc_socks = %d\n", tcp_connections.size(), rpc_sockets.size()); + } if (since_tcp >= ZT_LWIP_TCP_TIMER_INTERVAL) { prev_tcp_time = now; lwipstack->tcp_tmr(); @@ -381,9 +388,9 @@ void NetconEthernetTap::phyOnFileDescriptorActivity(PhySocket *sock,void **uptr, if(conn->dataSock) // Sometimes a connection may be closed via nc_recved, check first { //Mutex::Lock _l(lwipstack->_lock); - //lwipstack->_lock.lock(); + lwipstack->_lock.lock(); handle_write(conn); - //lwipstack->_lock.unlock(); + lwipstack->_lock.unlock(); } } else { @@ -515,7 +522,7 @@ int NetconEthernetTap::send_return_value(int fd, int retval, int _errno = 0) [I] ECONNABORTED - A connection has been aborted. [i] EFAULT - The addr argument is not in a writable part of the user address space. [-] EINTR - The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7). - [?] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative). + [I] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative). [I] EINVAL - (accept4()) invalid value in flags. [I] EMFILE - The per-process limit of open file descriptors has been reached. [ ] ENFILE - The system limit on the total number of open files has been reached. @@ -755,7 +762,8 @@ err_t NetconEthernetTap::nc_poll(void* arg, struct tcp_pcb *tpcb) * */ err_t NetconEthernetTap::nc_sent(void* arg, struct tcp_pcb *tpcb, u16_t len) -{fprintf(stderr, "nc_sent()\n"); +{ + //fprintf(stderr, "nc_sent()\n"); Larg *l = (Larg*)arg; if(len) { //fprintf(stderr, "ACKING len = %d, setting read-notify = true, (sndbuf = %d)\n", len, l->conn->pcb->snd_buf); @@ -1150,7 +1158,7 @@ void NetconEthernetTap::handle_write(TcpConnection *conn) // NOTE: this assumes that lwipstack->_lock is locked, either // because we are in a callback or have locked it manually. int err = lwipstack->_tcp_write(conn->pcb, &conn->buf, r, TCP_WRITE_FLAG_COPY); - lwipstack->_tcp_output(conn->pcb); + //lwipstack->_tcp_output(conn->pcb); if(err != ERR_OK) { fprintf(stderr, "handle_write(): error while writing to PCB, (err = %d)\n", err); return; diff --git a/netcon/libintercept.so.1.0 b/netcon/libintercept.so.1.0 index fa9cdf28402396459447d85e57defff480bb8223..de9dff34a97c2eb6e666dccbdf040c00f8dbf6d4 100755 GIT binary patch delta 9411 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 rcHCso8CVAq+djE-lQ|>D5|Q<7RaLNVt*R delta 9575 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