static int
handle_handshake_response (BlockTxClient *client)
{
    BlockTxInfo *info = client->info;
    struct evbuffer *input = client->recv_buf;
    HandshakeResponse rsp;

    if (evbuffer_get_length (input) < sizeof(rsp))
        return 0;

    evbuffer_remove (input, &rsp, sizeof(rsp));

    rsp.status = ntohl(rsp.status);
    rsp.version = ntohl(rsp.version);

    if (rsp.status == STATUS_OK) {
        seaf_debug ("Handshake OK.\n");

        client->version = MIN (rsp.version, BLOCK_PROTOCOL_VERSION);

        if (client->version == 1)
            blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key),
                                          client->key, client->iv);
        else if (client->version == 2)
            blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key),
                                          client->key_v2, client->iv_v2);
        else {
            seaf_warning ("Bad block protocol version %d.\n", rsp.version);
            info->result = BLOCK_CLIENT_FAILED;
            return -1;
        }

        seaf_debug ("Block protocol version %d.\n", client->version);

        init_frame_parser (client);

        if (send_authentication (client) < 0)
            return -1;

        return 0;
    } else if (rsp.status == STATUS_VERSION_MISMATCH) {
        seaf_warning ("The server refuse to accpet protocol version %d.\n"
                      "Remote version is %d.\n",
                      BLOCK_PROTOCOL_VERSION, rsp.version);
        /* this is a hard error. */
        info->result = BLOCK_CLIENT_FAILED;
        return -1;
    } else if (rsp.status == STATUS_INTERNAL_SERVER_ERROR) {
        seaf_warning ("Internal server error.\n");
        info->result = BLOCK_CLIENT_SERVER_ERROR;
        return -1;
    }

    seaf_warning ("Bad status code %d in handshake.\n", rsp.status);
    info->result = BLOCK_CLIENT_FAILED;
    return -1;
}
Example #2
0
bool KClient::Poll()
{
    switch(state){
    case TEST_INIT:
        if( GetState() == vce::VCE_STATE_ESTABLISHED ){
            std::cerr << "send ping" << std::endl;
            send_ping( vce::GetTime());
            state = TEST_PING_SENT;            
            break;
        } else {
            std::cerr << GetState() << ">" ;
            if( GetState() == vce::VCE_STATE_UNKNOWN ){
                return false;
            }
        }
        break;
    case TEST_PING_SENT:
        std::cerr << ">";
        break;
    case TEST_PING_RECEIVED:
        {
            
            // 新しいIDを生成して登録(sign up)する

            std::ostringstream idss;
            idss << "ringo" << time(NULL) << "." << g_id_generator;
            localAccountName = idss.str();
            localPassword = std::string("testpass");

            g_id_generator ++;
            send_signup( localAccountName.c_str(), localPassword.c_str());
            std::cerr << "signup" << std::endl;
            state = TEST_SIGNUP_SENT;

        }
        break;
    case TEST_SIGNUP_SENT:
        std::cerr << ">";
        break;
    case TEST_SIGNUP_RECEIVED:
        send_authentication( localAccountName.c_str(), localPassword.c_str());
        state = TEST_AUTHENTICATION_SENT;
        std::cerr << "auth" << std::endl;
        break;
        
    case TEST_AUTHENTICATION_SENT:
        std::cerr << ">";        
        break;
    case TEST_AUTHENTICATION_RECEIVED:
        send_createCharacter( "ringo" );
        state = TEST_CREATECHARACTER_SENT;
        std::cerr << "createchar" << std::endl;
        break;

    case TEST_CREATECHARACTER_SENT:
        std::cerr << ">";                
        break;
    case TEST_CREATECHARACTER_RECEIVED:
        std::cerr << "createchar ok." << std::endl;
        
        send_listCharacter();
        state = TEST_LISTCHARACTER_SENT;
        std::cerr << "listchar." << std::endl;
        break;
        
    case TEST_LISTCHARACTER_SENT:
        std::cerr << ">";                
        break;
    case TEST_LISTCHARACTER_RECEIVED:
        std::cerr << "listchar ok." << std::endl;
        send_login( "ringo" );        
        state = TEST_LOGIN_SENT;
        std::cerr << "login." << std::endl;        
        break;

    case TEST_LOGIN_SENT:
        std::cerr << ">";
        break;
    case TEST_LOGIN_RECEIVED:
        state = TEST_INGAME;
        break;
    case TEST_INGAME:
        {
            vce::VUint64 nowtimer = vce::GetTime();
            if( nowtimer > (vtimer+500) ){
                vtimer = nowtimer;
                std::cerr << ">";
                ingameSender();
                printStat();
            }
        }
        break;
    case TEST_LOGOUT_SENT:
        std::cerr << ">";
        break;
    case TEST_SESSION_CLOSED:
        break;
    case TEST_FINISHED:
        // do nothing
        std::cerr << ".";
        break;
    default:
        std::cerr << "invalid test state" << std::endl;        
        assert(0);
    }
    return true;    
}