2011-04-07 11:02:54 +02:00
|
|
|
#include "../oio.h"
|
2011-04-05 01:43:17 +02:00
|
|
|
#include "test.h"
|
2011-03-31 00:21:15 -07:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
2011-04-05 01:43:17 +02:00
|
|
|
#include <stdio.h>
|
2011-03-31 00:21:15 -07:00
|
|
|
|
|
|
|
static int completed_pingers = 0;
|
|
|
|
|
2011-04-07 04:51:59 +02:00
|
|
|
#define NUM_PINGS 1000
|
2011-04-05 01:43:17 +02:00
|
|
|
|
2011-03-31 00:21:15 -07:00
|
|
|
/* 64 bytes is enough for a pinger */
|
2011-04-07 04:51:59 +02:00
|
|
|
#define BUFSIZE 10240
|
|
|
|
|
|
|
|
static char PING[] = "PING\n";
|
2011-03-31 00:21:15 -07:00
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int pongs;
|
|
|
|
int state;
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_handle handle;
|
|
|
|
oio_req connect_req;
|
|
|
|
oio_req read_req;
|
|
|
|
oio_buf buf;
|
2011-03-31 00:21:15 -07:00
|
|
|
char read_buffer[BUFSIZE];
|
2011-04-07 04:51:59 +02:00
|
|
|
} pinger_t;
|
|
|
|
|
|
|
|
void pinger_try_read(pinger_t* pinger);
|
2011-03-31 00:21:15 -07:00
|
|
|
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void pinger_on_close(oio_handle* handle, oio_err err) {
|
2011-04-07 04:51:59 +02:00
|
|
|
pinger_t* pinger = (pinger_t*)handle->data;
|
2011-04-01 00:09:06 +02:00
|
|
|
|
2011-03-31 00:21:15 -07:00
|
|
|
assert(!err);
|
2011-04-07 04:51:59 +02:00
|
|
|
assert(NUM_PINGS == pinger->pongs);
|
|
|
|
|
|
|
|
free(pinger);
|
|
|
|
|
2011-03-31 00:21:15 -07:00
|
|
|
completed_pingers++;
|
|
|
|
}
|
|
|
|
|
2011-04-07 04:51:59 +02:00
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void pinger_after_write(oio_req *req) {
|
2011-04-07 04:51:59 +02:00
|
|
|
free(req);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pinger_write_ping(pinger_t* pinger) {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_req *req;
|
2011-04-07 04:51:59 +02:00
|
|
|
int r;
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
req = (oio_req*)malloc(sizeof(*req));
|
|
|
|
oio_req_init(req, &pinger->handle, pinger_after_write);
|
|
|
|
r = oio_write2(req, (char*)&PING);
|
2011-04-07 04:51:59 +02:00
|
|
|
assert(!r);
|
|
|
|
}
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void pinger_after_read(oio_req* req, size_t nread) {
|
2011-04-01 00:09:06 +02:00
|
|
|
unsigned int i;
|
2011-04-07 04:51:59 +02:00
|
|
|
pinger_t* pinger;
|
|
|
|
|
|
|
|
pinger = (pinger_t*)req->handle->data;
|
2011-03-31 00:21:15 -07:00
|
|
|
|
|
|
|
if (nread == 0) {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_close(&pinger->handle);
|
2011-03-31 00:21:15 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now we count the pings */
|
|
|
|
for (i = 0; i < nread; i++) {
|
2011-04-07 04:51:59 +02:00
|
|
|
assert(pinger->buf.base[i] == PING[pinger->state]);
|
|
|
|
pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
|
|
|
|
if (pinger->state == 0) {
|
|
|
|
pinger->pongs++;
|
|
|
|
if (pinger->pongs < NUM_PINGS) {
|
|
|
|
pinger_write_ping(pinger);
|
2011-03-31 00:21:15 -07:00
|
|
|
} else {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_close(&pinger->handle);
|
2011-04-01 00:09:06 +02:00
|
|
|
return;
|
2011-03-31 00:21:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-04-01 00:09:06 +02:00
|
|
|
|
2011-04-07 04:51:59 +02:00
|
|
|
pinger_try_read(pinger);
|
2011-03-31 00:21:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-07 04:51:59 +02:00
|
|
|
void pinger_try_read(pinger_t* pinger) {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_read(&pinger->read_req, &pinger->buf, 1);
|
2011-03-31 00:21:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
void pinger_on_connect(oio_req *req, oio_err err) {
|
2011-04-07 04:51:59 +02:00
|
|
|
pinger_t *pinger = (pinger_t*)req->handle->data;
|
2011-03-31 00:21:15 -07:00
|
|
|
|
2011-04-05 01:43:17 +02:00
|
|
|
if (err) {
|
|
|
|
assert(0);
|
|
|
|
}
|
|
|
|
|
2011-04-07 04:51:59 +02:00
|
|
|
pinger_try_read(pinger);
|
|
|
|
pinger_write_ping(pinger);
|
|
|
|
}
|
2011-03-31 00:21:15 -07:00
|
|
|
|
|
|
|
|
2011-04-14 01:35:39 +02:00
|
|
|
int pinger_new() {
|
2011-04-07 11:02:54 +02:00
|
|
|
struct sockaddr_in client_addr = oio_ip4_addr("0.0.0.0", 0);
|
2011-04-14 01:35:39 +02:00
|
|
|
struct sockaddr_in server_addr = oio_ip4_addr("127.0.0.1", TEST_PORT);
|
2011-04-07 04:51:59 +02:00
|
|
|
pinger_t *pinger;
|
2011-03-31 00:21:15 -07:00
|
|
|
|
2011-04-07 04:51:59 +02:00
|
|
|
pinger = (pinger_t*)malloc(sizeof(*pinger));
|
|
|
|
pinger->state = 0;
|
|
|
|
pinger->pongs = 0;
|
|
|
|
pinger->buf.len = sizeof(pinger->read_buffer);
|
|
|
|
pinger->buf.base = (char*)&pinger->read_buffer;
|
2011-03-31 00:21:15 -07:00
|
|
|
|
2011-04-05 01:43:17 +02:00
|
|
|
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
|
2011-04-07 11:02:54 +02:00
|
|
|
if (oio_tcp_handle_init(&pinger->handle, pinger_on_close, (void*)pinger)) {
|
2011-04-07 04:51:59 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We are never doing multiple reads/connects at a time anyway. */
|
|
|
|
/* so these handles can be pre-initialized. */
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_req_init(&pinger->connect_req, &pinger->handle, pinger_on_connect);
|
|
|
|
oio_req_init(&pinger->read_req, &pinger->handle, pinger_after_read);
|
2011-04-01 00:09:06 +02:00
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_bind(&pinger->handle, (struct sockaddr*)&client_addr);
|
|
|
|
return oio_connect(&pinger->connect_req, (struct sockaddr*)&server_addr);
|
2011-03-31 00:21:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-05 01:43:17 +02:00
|
|
|
TEST_IMPL(ping_pong) {
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_init();
|
2011-03-31 00:21:15 -07:00
|
|
|
|
2011-04-14 01:35:39 +02:00
|
|
|
if (pinger_new()) {
|
2011-03-31 00:21:15 -07:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2011-04-07 11:02:54 +02:00
|
|
|
oio_run();
|
2011-03-31 00:21:15 -07:00
|
|
|
|
|
|
|
assert(completed_pingers == 1);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|