void rttable::add(const cageaddr &addr) { int i; if (*addr.id == m_id) return; i = id2i(*addr.id); if (i < 0 || m_nodes.find(*addr.id) != m_nodes.end()) return; if (m_table.find(i) == m_table.end()) { m_table[i].push_back(addr); m_nodes.insert(*addr.id); } else { std::list<cageaddr> &row = m_table[i]; std::list<cageaddr>::iterator it; for (it = row.begin(); it != row.end(); ++it) { if (*it->id == *addr.id) { row.erase(it); row.push_back(addr); return; } } if ((int)m_table[i].size() < max_entry) { m_table[i].push_back(addr); m_nodes.insert(*addr.id); } else if (m_ping_send.find(i) != m_ping_send.end()){ return; } else { uint32_t nonce; for (;;) { nonce = m_rnd(); if (m_ping_wait.find(nonce) == m_ping_wait.end()) break; } // start timer cageaddr &addr_old(m_table[i].front()); timer_ptr func(new timer_ping); timeval tval; func->m_rttable = this; func->m_addr_old = addr_old; func->m_addr_new = addr; func->m_nonce = nonce; func->m_i = i; tval.tv_sec = ping_timeout; tval.tv_usec = 0; m_timer.set_timer(func.get(), &tval); // set state m_ping_wait[nonce] = func; m_ping_send.insert(i); // send ping send_ping(addr_old, nonce); } } }
void CThread::AsciiForceError(int key, msghdr &msghdr) { ErrType et; bool expDropConn; string expText; string gotText; Action act; struct iovec *iovP; char cp0[256]; // iov0 replacement buffer bool doubleRx; // // any command that has data following the header should not be tested for aUnkCmd // the server reads the header, replies (24 bytes) and then reads expecting a header // but normally gets an invalid magic number. // // the data type test is ignored because the server ignores the data type // static const Action action[eCmdCnt][eErrCnt] = { // must match ECmd order // magic cmd key { aSkip, aError2, aSkip, aSkip }, // set cmd { aSkip, aError2, aSkip, aSkip }, // add cmd { aSkip, aError2, aSkip, aSkip }, // rep cmd { aSkip, aError2, aSkip, aSkip }, // app cmd { aSkip, aError2, aSkip, aSkip }, // pre cmd { aSkip, aError2, aSkip, aSkip }, // cas cmd { aSkip, aError, aSkip, aSkip }, // get cmd { aSkip, aSkip, aSkip, aSkip }, // gets cmd { aSkip, aSkip, aSkip, aSkip }, // getk cmd { aSkip, aSkip, aSkip, aSkip }, // getr cmd { aSkip, aError, aSkip, aSkip }, // gat cmd { aSkip, aError, aSkip, aSkip }, // inc cmd { aSkip, aError, aSkip, aSkip }, // dec cmd { aSkip, aError, aSkip, aSkip }, // del cmd { aSkip, aError, aSkip, aSkip }, // touch cmd { aSkip, aError, aSkip, aSkip }, // stat cmd { aSkip, aError, aSkip, aSkip }, // ver cmd { aSkip, aSkip, aSkip, aSkip }, // nop cmd }; expText = ""; do { et = (ErrType)(m_rnd() % eErrCnt); } while(et == eMagic || et == eDataType || et == eKeyLen); // no magic in ascii iovP = msghdr.msg_iov; memcpy(cp0, iovP[0].iov_base, iovP[0].iov_len); iovP[0].iov_base = cp0; act = action[m_cmdCmd][et]; if(m_trace2) { printf("command %s error %s action %s\n", cmdStr[m_cmdCmd], errStr[et], actStr[act]); } switch(et) { // do the actual error case eMagic: assert(0); break; case eCmd: cp0[0] = 'X'; // no command starts with X break; case eKeyLen: iovP[1].iov_base = 0; // remove key iovP[1].iov_len = 0; break; case eDataType: // ascii has no datatype break; default: return; assert(0); } expDropConn = false; doubleRx = false; expText = ""; switch(act) { case aTAS: // test and stop break; case aSkip: if(m_trace2) { printf("\n"); } return; // legal case case aError: expText = "ERROR\r\n"; break; case aError2: expText = "ERROR\r\n"; doubleRx = true; break; case aDropConn: expDropConn = true; break; case aUnkCmd: expText = "Unknown command"; break; case aInvArg: expText = "Invalid arguments"; expDropConn = true; break; case aNotFound: expText = "Not found"; expDropConn = true; break; default: assert(0); } if(m_trace2) { printf("forcing %s error ", errStr[et]); } SendMsg(msghdr); if(act == aTAS) { printf("\nTAS Hit enter to continue or ^C to exit "); fflush(stdout); getc(stdin); } if(expText.length() != 0) { if(m_trace2) { printf("expText "); } m_tcpRespBufLen = recv(m_tcpFd, m_tcpRespBuf, expText.length(), 0); if(m_trace2) { printf("recieved %ld bytes ", m_tcpRespBufLen); } } if(expDropConn == true) { // expect connection to drop fd_set read; timeval tv = {0,100000}; // wait 1 sec FD_ZERO(&read); FD_SET(m_tcpFd, &read); int sel = select(m_tcpFd + 1, &read, 0, 0, &tv); if(m_trace2) { printf("sel %d ", sel); } if(sel > 0) { m_tcpRespBufLen = recv(m_tcpFd, m_tcpRespBuf, RESP_BUF_SIZE, 0); if(m_trace2) { printf("recieved %ld bytes ", m_tcpRespBufLen); } } closesocket(m_tcpFd); TcpSocket(); // reopen } if(expText.length() != 0) { m_tcpRespBuf[m_tcpRespBufLen] = 0; if(expText.compare(m_tcpRespBuf) != 0) { gotText = m_tcpRespBuf; ErrorMsg("Error test failed, ", &expText, &gotText); } } if(doubleRx) { m_tcpRespBufLen = recv(m_tcpFd, m_tcpRespBuf, RESP_BUF_SIZE, 0); } if(1) { // possible connection to drop fd_set read; timeval tv = {0,10000}; // wait FD_ZERO(&read); FD_SET(m_tcpFd, &read); int sel = select(m_tcpFd + 1, &read, 0, 0, &tv); m_tcpRespBufLen = 1; if(sel > 0) { m_tcpRespBufLen = recv(m_tcpFd, m_tcpRespBuf, RESP_BUF_SIZE, 0); if(m_trace2) { printf("recieved %ld bytes ", m_tcpRespBufLen); } } if(sel < 0 || m_tcpRespBufLen == 0 || (int)m_tcpRespBufLen == -1) { closesocket(m_tcpFd); TcpSocket(); // reopen } } if(m_trace2) { printf("\n\n"); } m_tcpRespBufLen = 0; }