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 zcmd5?iGNd7zQ5xU1A|p~n9&V_VI8O#0fq?%&gbVNpJU7UhNxSZ z!Y@aau=%_&`WCjC`=U!&DgQ%siTYiJ|4j5Rs=CwZKNDk#Vuk!dVheNeNlA0n(+U1R zCNak1`JTRmnTdbjw_5!sk(VV8RNqVFwGQF}gmN zU!P)SDZC{mM}0ev-=8wkdLj-%t~_8qUHPwIFd_Rvtyu2P>J9v4ibFjb=Z{J)R@D=I zczN0&)|byto5?2g6IL5PmKN`$44J0ZL4Ga3i0PKEzw`6Y9{hSaEmUZ+3SSx28E1-*jiv7~gDX-oY`>MCSJ0 z=d`0LE@OOOxqat+$AYO_u$CaxW_Sf+Ib|C-`(rS8NNEGPi}vcY1s@67g8BKEV6Z(Q zdkk>fcLFL@>VgHjU%~y#4}yUN%jNF>%FH+7isE)gHkux!H6d+{%3}Lmbmx2mBc7fujf$U240_
    o|~Dcrd;4RW)`xkd{Jh9wcn5Y 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 delta 9575 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