static void * rr_thread(void *arg) { struct rr *r = arg; #ifdef UNUSED_TEST_CODE if (r->server) { cpu_set_t cpu; CPU_ZERO(&cpu); CPU_SET(2, &cpu); if (0 != pthread_setaffinity_np(pthread_self(), sizeof(cpu), &cpu)) { ERROR_DIE("pthread_setaffinity failed"); } } #endif #if CHECK_RTO_RETRANS checker_add_so(r->so); #endif if (r->server) { while (1) { int msg_len; char *buf; int s = read(r->so, r->buf, sizeof(r->buf)); if (s < 0) { log_msg("%d: read returns an error. %s(%d). stopping\n", r->id, strerror(errno), errno); goto exit; } if (s == 0) { log_msg("%d: read returns eof. stopping\n", r->id); goto exit; } if (s < sizeof(msg_len)) { log_msg("%d: read only %d bytes. stopping\n", r->id, s); goto exit; } buf = r->buf; msg_len = *((int*)buf); if (msg_len > sizeof(r->buf) || msg_len <= 0) { log_msg("%d: invalid msg_len %d. stopping\n", r->id, msg_len); goto exit; } if (s > msg_len) { log_msg("%d: client sent too much. msg_len=%d s=%d. stopping\n", r->id, msg_len, s); goto exit; } if (s < msg_len) { int rem = msg_len - s; while (rem > 0) { s = read(r->so, r->buf+msg_len-rem, rem); if (s > 0) rem -= s; else if (s < 0) { log_msg("%d: read returns an error. %s(%d). stopping\n", r->id, strerror(errno), errno); goto exit; } else if (s == 0) { log_msg("%d: read returns eof. stopping\n", r->id); goto exit; } } } s = write(r->so, r->buf, msg_len); if (s != msg_len) { log_msg("%d: write failed. s=%d msg_len=%d error=%s(%d). stopping\n", r->id, s, msg_len, strerror(errno), errno); goto exit; } } } else { memset(r->buf, 0, sizeof(r->buf)); while (1) { int s, rem; uint64_t msec; char *buf; // Sleep a little and then send a request and receive a response if (r->sleep > 0) usleep(r->sleep); msec = getmsec(); buf = r->buf; *((int*)buf) = r->msg_len; // msg length in the first 4 bytes s = write(r->so, r->buf, r->msg_len); if (s != r->msg_len) { log_msg("%d: write failed. s=%d msg_len=%d error=%s(%d). stopping\n", r->id, s, r->msg_len, strerror(errno), errno); goto exit; } rem = r->msg_len; while (rem > 0) { s = read(r->so, r->buf+r->msg_len-rem, rem); if (s > 0) rem -= s; else if (s < 0) { log_msg("%d: read returns an error. %s(%d). stopping\n", r->id, strerror(errno), errno); goto exit; } else if (s == 0) { log_msg("%d: read returns eof. stopping\n", r->id); goto exit; } } r->stat_count++; msec = getmsec() - msec; hist_inc(&r->hist, (uint32_t)msec); } } exit: #if CHECK_RTO_RETRANS checker_remove_so(r->so); #endif // For server, free the conn structure. The main loop does not. if (r->server) { free(r); } return NULL; }
static struct network_conf * parse_nconf(gnc_t gnc, void *closure) { int c; char *token; struct network_conf *nconf; nconf = calloc(1, sizeof(struct network_conf)); if(nconf == NULL) goto error; c = gnc(closure); if(c < -1) goto error; c = skip_whitespace(c, gnc, closure); if(c < -1 || c == '\n' || c == '#') goto error; c = getstring(c, &token, gnc, closure); if(c < -1 || token == NULL) goto error; nconf->ifname = token; while(c >= 0 && c != '\n') { c = skip_whitespace(c, gnc, closure); if(c == '\n' || c == '#') { c = skip_to_eol(c, gnc, closure); break; } c = getword(c, &token, gnc, closure); if(c < -1) goto error; if(strcmp(token, "rxcost") == 0) { int cost; c = getint(c, &cost, gnc, closure); if(c < -1 || cost <= 0 || cost > 0xFFFF) goto error; nconf->cost = cost; } else if(strcmp(token, "hello-interval") == 0) { int interval; c = getmsec(c, &interval, gnc, closure); if(c < -1 || interval <= 0 || interval > 10 * 0xFFFF) goto error; nconf->hello_interval = interval; } else if(strcmp(token, "update-interval") == 0) { int interval; c = getmsec(c, &interval, gnc, closure); if(c < -1 || interval <= 0 || interval > 10 * 0xFFFF) goto error; nconf->update_interval = interval; } else if(strcmp(token, "wired") == 0) { int v; c = getbool(c, &v, gnc, closure); if(c < -1) goto error; nconf->wired = v; } else if(strcmp(token, "link-quality") == 0) { int v; c = getbool(c, &v, gnc, closure); if(c < -1) goto error; nconf->lq = v; } else if(strcmp(token, "split-horizon") == 0) { int v; c = getbool(c, &v, gnc, closure); if(c < -1) goto error; nconf->split_horizon = v; } else { goto error; } free(token); } return nconf; error: free(nconf); return NULL; }