示例#1
0
        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);
                        }
                }
        }
示例#2
0
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;
}