int strategy_choose_remote_addr(vpn_ctx_t *ctx) { // rules: // 1. if there isn't any address received from within ADDR_TIMEOUT // choose latest // 2. if there are some addresses received from within ADDR_TIMEOUT // choose randomly from them // // how we do this efficiently // 1. scan once and find latest, total number of not timed out addresses // 2. if number <= 1, use latest // 3. if number > 1, generate random i in (0, number), // scan again and pick (i)th address not timed out int i, total_not_timed_out = 0, chosen; time_t now; addr_info_t *latest = NULL, *temp; if (ctx->nknown_addr == 0) { return 0; } time(&now); for (i = 0; i < ctx->nknown_addr; i++) { temp = &ctx->known_addrs[i]; if (latest == NULL || latest->last_recv_time < temp->last_recv_time) { latest = temp; } if (now - temp->last_recv_time <= ADDR_TIMEOUT) { total_not_timed_out++; } } if (total_not_timed_out <= 1) { load_addr(latest, &ctx->remote_addr, &ctx->remote_addrlen); } else { chosen = randombytes_uniform(total_not_timed_out); total_not_timed_out = 0; for (i = 0; i < ctx->nknown_addr; i++) { temp = &ctx->known_addrs[i]; if (now - temp->last_recv_time <= ADDR_TIMEOUT) { if (total_not_timed_out == chosen) { load_addr(temp, &ctx->remote_addr, &ctx->remote_addrlen); break; } total_not_timed_out++; } } } return 0; }
int read_ModR_M(swaddr_t eip, Operand *rm, Operand *reg) { ModR_M m; m.val = instr_fetch(eip, 1); // Log("m.val = %02x", m.val); reg->type = OP_TYPE_REG; reg->reg = m.reg; if(m.mod == 3) { rm->type = OP_TYPE_REG; rm->reg = m.R_M; switch(rm->size) { case 1: rm->val = reg_b(m.R_M); break; case 2: rm->val = reg_w(m.R_M); break; case 4: rm->val = reg_l(m.R_M); break; default: assert(0); } #ifdef DEBUG switch(rm->size) { case 1: sprintf(rm->str, "%%%s", regsb[m.R_M]); break; case 2: sprintf(rm->str, "%%%s", regsw[m.R_M]); break; case 4: sprintf(rm->str, "%%%s", regsl[m.R_M]); break; } #endif return 1; } else { int instr_len = load_addr(eip, &m, rm); rm->val = swaddr_read(rm->addr, rm->size, R_DS); //TODO DS or SS return instr_len; } }
DWORD Read5(DWORD d) { word_20 p = 0; load_addr(&p,d,5); return p; }