Changeset - 27eb6c6418f6
[Not reviewed]
default
0 9 0
Nathan Brink (binki) - 15 years ago 2010-07-21 23:03:26
ohnobinki@ohnopublishing.net
Handle resolving hostnames gracefully.
Fix support for hostname:port in remoteio.
Added timeout parameter to multiio_poll().
Fix stupid mistakes in distrenslave's read handler.
The server and client may not sit and play table tennis at last :-D.
9 files changed with 57 insertions and 36 deletions:
0 comments (0 inline, 0 general)
src/common/multiio.c
Show inline comments
 
@@ -171,20 +171,20 @@ int multiio_poll_invoke_handlers(struct 
 
			handler_info->handler_data,
 
			travinfo->socket_info->socket_data);
 

	
 
  return TRUE;
 
}
 

	
 
int multiio_poll(multiio_context_t context)
 
int multiio_poll(multiio_context_t context, int timeout)
 
{
 
  size_t counter;
 
  struct multiio_poll_travinfo travinfo;
 

	
 
  int ret;
 

	
 
  ret = poll(context->pollfds, context->nfds, -1);
 
  ret = poll(context->pollfds, context->nfds, timeout);
 
  if(ret == -1)
 
    {
 
      perror("poll");
 
    }
 

	
 
  for(counter = 0; counter < context->nfds; counter ++)
src/common/multiio.h
Show inline comments
 
@@ -64,17 +64,21 @@ multiio_context_t multiio_context_new();
 

	
 
   @param context the context to destroy.
 
 */
 
int multiio_context_free(multiio_context_t context);
 

	
 
/**
 
   Call poll() on the registered sockets and react to events accordingly.
 

	
 
   @param context the context which sockets and handlers were registered with
 
 * Call poll() on the registered sockets and react to events accordingly.
 
 *
 
 * @param context the context which sockets and handlers were registered with
 
 *
 
 * @param timeout see poll(3p). The number of milliseconds to wait for
 
 * a request before returning. 0 for immediate return if no activity
 
 * and -1 for waiting until some activity happens before returning.
 
 */
 
int multiio_poll(multiio_context_t context);
 
int multiio_poll(multiio_context_t context, int timeout);
 

	
 
/**
 
   Registers a new socket type/classification for use with this multiio_context.
 

	
 
   @param context the multiio context to register this type with.
 
   @param new_type a pointer to a type which this function will set to the value of
src/common/protocol.c
Show inline comments
 
@@ -73,18 +73,33 @@ int distren_request_send(struct remoteio
 
}
 

	
 
int distren_request_new_fromdata(struct distren_request **req, void *data, size_t len)
 
{
 
  struct distren_request *newreq;
 

	
 
#if 0
 
  size_t counter;
 
  uint32_t debugtmp;
 
#endif
 

	
 
  if(len < sizeof(struct distren_request))
 
    return 1;
 

	
 
  if( ((struct distren_request *)data)->magic != DISTREN_REQUEST_MAGIC )
 
    {
 
      fprintf(stderr, "packet doesn't match magic stuffs\n");
 
      fprintf(stderr, "packet doesn't match magic stuffs");
 
#if 0
 
      fputs("\n\tmagic=`", stderr);
 
      debugtmp = DISTREN_REQUEST_MAGIC;
 
      for(counter = 0; counter < sizeof(uint32_t); counter ++)
 
	putc(((char *)&debugtmp)[counter], stderr);
 
      fputs("'\n\t`", stderr);
 
      for(counter = 0; counter < sizeof(struct distren_request); counter ++)
 
	putc(((char *)data)[counter], stderr);
 
      fputs("'\n", stderr);
 
#endif
 
      return 1;
 
    }
 

	
 
  newreq = malloc(sizeof(struct distren_request));
 
  if(!newreq)
 
    {
src/common/remoteio.c
Show inline comments
 
@@ -736,12 +736,14 @@ int _remoteio_tcp_open(struct remoteio *
 
  char *hostname;
 
  char *port;
 

	
 
  struct addrinfo addrinfo_hints;
 
  struct addrinfo *addrinfo_res;
 

	
 
  static char *default_port = REMOTEIO_DEFAULT_PORT;
 

	
 
  /**
 
     only hostname should be free()-ed, not port,
 
     because both are from the same block of malloc()-ed
 
     memory
 
   */
 
  hostname = strdup(server->hostname);
 
@@ -752,27 +754,31 @@ int _remoteio_tcp_open(struct remoteio *
 
  if(*port)
 
    {
 
      *port = '\0';
 
      port ++;
 
    }
 
  else
 
    port = REMOTEIO_DEFAULT_PORT;
 
    port = default_port;
 

	
 
  memset(&addrinfo_hints, '\0', sizeof(struct addrinfo));
 
  addrinfo_hints.ai_family = AF_UNSPEC;
 
#ifdef _WIN32
 
  /* windows lacks stuff documented in POSIX, I guess :-( */
 
  addrinfo_hints.ai_flags = 0;
 
#else
 
  addrinfo_hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
 
#endif
 
  addrinfo_hints.ai_socktype = SOCK_STREAM;
 

	
 
  tmp = getaddrinfo(server->hostname, port, &addrinfo_hints, &addrinfo_res);
 
  tmp = getaddrinfo(hostname, port, &addrinfo_hints, &addrinfo_res);
 
  if(tmp)
 
    fprintf(stderr, "error resolving %s:%s: %s\n", server->hostname, port, gai_strerror(tmp));
 
    {
 
      fprintf(stderr, "error resolving %s:%s: %s\n", server->hostname, port, gai_strerror(tmp));
 
      free(hostname);
 
      return 1;
 
    }
 
  fprintf(stderr, "connecting to %s[%s]:%s\n", server->hostname, addrinfo_res->ai_canonname, port);
 

	
 
  free(hostname);
 

	
 
  sock = socket(addrinfo_res->ai_family, SOCK_STREAM, addrinfo_res->ai_protocol);
 
  if(sock == -1)
src/common/request.c
Show inline comments
 
@@ -25,20 +25,20 @@
 
int distren_request_free_with_data(struct distren_request *req, void *data)
 
{
 
  free(data);
 
  return distren_request_free(req);
 
}
 

	
 
uint32_t distren_request_poing(struct distren_request **req, void **data, short is_ping, const void *poing_cookie, size_t poing_data_len)
 
int distren_request_poing(struct distren_request **req, void **data, short is_ping, const void *poing_cookie, size_t poing_data_len)
 
{
 
  enum distren_request_type type;
 

	
 
  if(is_ping)
 
    type = DISTREN_REQUEST_PING;
 
  else
 
    type = DISTREN_REQUEST_PONG;
 
  distren_request_new(req, poing_data_len, type);
 
  (*data) = malloc(poing_data_len);
 
  memcpy(*data, poing_cookie, poing_data_len);
 

	
 
  return (uint32_t)poing_data_len;
 
  return 0;
 
}
src/server/distrend.c
Show inline comments
 
@@ -184,13 +184,13 @@ int main(int argc, char *argv[])
 
  /* Main Loop */
 
  general_info.config->die = 0;
 
  while(!general_info.config->die)
 
    {
 
      int clientrequest = 0; /*< temporary example variable, will be replaced when we can handle messages */
 

	
 
      multiio_poll(multiio);
 
      multiio_poll(multiio, 15000);
 

	
 
      tabletennis_serve(general_info.config->listens->tabletennis);
 

	
 
      /* Run the watchdog, @TODO: like every 10 mins or something */
 
      frame_watchdog(general_info.conn);
 

	
 
@@ -576,13 +576,13 @@ int interactiveTest(int test, multiio_co
 
       fprintf(stderr,"Started Frame!\n");
 
       break;
 

	
 
     case 5:
 
       while(1)
 
	 {
 
	   multiio_poll(multiio);
 
	   multiio_poll(multiio, 15000);
 
	   tabletennis_serve(geninfo->config->listens->tabletennis);
 
	 }
 
       break;
 
       
 
     case 0:
 
       test = 0;
src/server/listen.c
Show inline comments
 
@@ -58,17 +58,12 @@ int listen_handle_error(multiio_context_
 
			int fd,
 
			short revent,
 
			struct distrend_listens *listens,
 
			int *port);
 

	
 
/*** TO BE MOVED TO REMOTEIO */
 
int listen_handle_read(multiio_context_t multiio,
 
		       int fd,
 
		       short revent,
 
		       struct distrend_listens *listens,
 
		       struct distrend_client *client);
 
int listen_handle_existence(multiio_context_t multiio,
 
			    int fd,
 
			    short revent,
 
			    struct distrend_listens *listens,
 
			    struct distrend_client *client);
 

	
 
@@ -192,15 +187,12 @@ int listen_handle_error(multiio_context_
 
  free(port);
 

	
 
  return 0;
 
}
 

	
 

	
 
//int listen_handle_read(struct distrend_listens *listens,
 
//			struct distrend_client *client)
 

	
 
/**
 
 * an important thing to handle
 
 *
 
 * @deprecated to be replaced with table_tennis
 
 */
 
int listen_handle_existence(multiio_context_t multiio,
 
@@ -346,12 +338,15 @@ int listen_handle_accept(multiio_context
 
  */
 
size_t distrend_listen_read_handle(struct remoteio *rem, struct distrend_listens *listens, void *buf, size_t len, struct distrend_client *client)
 
 {
 
   struct distren_request *req;
 
   void *reqdata;
 

	
 
   size_t used_len;
 

	
 
   used_len = 0;
 
   /**
 
    * Manage input, etc.
 
    */
 
   if(client->expectlen == 0)
 
     {
 
       /* search out header from input so far */
 
@@ -408,22 +403,23 @@ size_t distrend_listen_read_handle(struc
 
	  distren_request_free(req);
 
	  return 1;
 
	}
 
      memcpy(reqdata, ((void *)buf) + sizeof(struct distren_request), req->len);
 

	
 
      client->expectlen = 0;
 
      used_len = sizeof(struct distren_request) + req->len;
 

	
 
      distrend_dispatch_request(listens, rem, client, req, reqdata);
 
      free(reqdata);
 
      distren_request_free(req);
 

	
 
      /* I actually just used recursion in non-LISP code! :-D */
 
      return req->len + distrend_listen_read_handle(rem, listens, buf + req->len, len - req->len, client);
 
      return used_len + distrend_listen_read_handle(rem, listens, buf + req->len, len - req->len, client);
 
    }
 

	
 
  return 0;
 
  return used_len;
 
}
 

	
 
/**
 
 * Handle cleaning up after remoteio_close() has been called. This includes cleaning up the struct distrend_client and stuffs
 
 */
 
void distrend_listen_remoteio_handle_close(struct distrend_listens *listens, struct distrend_client *client)
 
@@ -569,16 +565,16 @@ int _distrend_dispatch_request_trav(stru
 
    (*handler_info->handler)(data->geninfo, data->client, data->req->len, data->req_data);
 

	
 
  return TRUE;
 
}
 

	
 
/**
 
   helper for listen_handle_read() which looks up the correct
 
   helper for distrend_listen_read_handle() which looks up the correct
 
   request handler and handles handing the the request to the
 
   handler. :-p
 
 */
 
*/
 
int distrend_dispatch_request(struct distrend_listens *listens, struct remoteio *rem, struct distrend_client *client, struct distren_request *req, void *reqdata)
 
{
 
  struct distrend_dispatch_request_data data;
 

	
 
  data.geninfo = listens->geninfo;
 
  data.client = client;
 
@@ -586,7 +582,6 @@ int distrend_dispatch_request(struct dis
 
  data.req_data = reqdata;
 

	
 
  list_traverse(listens->request_handlers, &data, (list_traverse_func_t)&_distrend_dispatch_request_trav, LIST_FRNT | LIST_SAVE);
 

	
 
  return 0;
 
}
 

	
src/server/slave.c
Show inline comments
 
@@ -227,13 +227,13 @@ int main(int argc, char *argv[])
 
    fprintf(stderr, "Running..");
 

	
 

	
 
  // Main loop
 
  while(!slave_state.quit)
 
    {
 
      multiio_poll(multiio);
 
      multiio_poll(multiio, 15000);
 

	
 
      if(slave_state.quit)
 
	break;
 

	
 
    // request work
 
    fprintf(stderr, "Waiting...\n");
 
@@ -390,12 +390,13 @@ static size_t distren_slave_remoteio_rea
 
  struct distren_request *req, *my_req;
 
  void *req_data, *my_req_data;
 

	
 
  size_t to_return;
 

	
 
  size_t counter;
 
  fprintf(stderr, "expected to eat %d bytes\n", len);
 

	
 
  /* to_return shall record how much of buf we've eaten already */
 
  to_return = 0;
 

	
 
  if(!slave_state->copyright_done)
 
    {
 
@@ -430,20 +431,20 @@ static size_t distren_slave_remoteio_rea
 
  while(1)
 
    {
 
      /* if we haven't read a full header yet: */
 
      if(!slave_state->expectlen)
 
	{
 
	  if(len < sizeof(struct distren_request))
 
	    return 0;
 
	    return to_return;
 

	
 
	  /* figure out how much we need to read in before we can get anywhere */
 
	  if(distren_request_new_fromdata(&req, buf, len))
 
	    {
 
	      fprintf(stderr, "Failing to interpret data from server, exiting\n");
 
	      slave_state->quit = 1;
 
	      return 0;
 
	      return to_return;
 
	    }
 
	  slave_state->expectlen = sizeof(struct distren_request) + req->len;
 
	  distren_request_free(req);
 
	}
 

	
 
      if(slave_state->expectlen
 
@@ -462,14 +463,14 @@ static size_t distren_slave_remoteio_rea
 
	      break;
 

	
 
	    case DISTREN_REQUEST_PING:
 
	      fprintf(stderr, "PONG ! :-D\n");
 

	
 
	      distren_request_poing(&my_req, &my_req_data, 0, req_data, req->len);
 
	      remoteio_write(slave_state->rem, &my_req, sizeof(struct distren_request));
 
	      remoteio_write(slave_state->rem, &my_req_data, req->len);
 
	      remoteio_write(slave_state->rem, my_req, sizeof(struct distren_request));
 
	      remoteio_write(slave_state->rem, my_req_data, req->len);
 
	      distren_request_free_with_data(my_req, my_req_data);
 
	      break;
 

	
 
	    case DISTREN_REQUEST_DISCONNECT:
 
	      /* hopefully this ends up being a useful message... */
 
	      printf("You have been disconnected: \"");
 
@@ -481,19 +482,20 @@ static size_t distren_slave_remoteio_rea
 

	
 
	    default:
 
	      fprintf(stderr, "something\n");
 
	      break;
 
	    }
 

	
 
	  counter = req->len + sizeof(struct distren_request);
 

	
 
	  distren_request_free(req);
 
	  slave_state->expectlen = 0;
 

	
 
	  counter = req->len + sizeof(struct distren_request);
 

	
 
	  len -= counter;
 
	  buf += counter;
 
	  to_return += counter;
 
	}
 
    }
 

	
 
  fprintf(stderr, "ate %d bytes\n", to_return);
 
  return to_return;
 
}
src/server/tabletennis.c
Show inline comments
 
@@ -80,25 +80,24 @@ int tabletennis_serve(tabletennis_t tabl
 
  struct timespec time_now;
 
  struct distrend_client *client;
 
  time_t time_next_check;
 

	
 
  struct distren_request *req;
 
  void *req_data;
 
  size_t req_len;
 

	
 
  clock_gettime(CLOCK_MONOTONIC, &time_now);
 

	
 
  time_next_check = time_now.tv_sec + tabletennis->pong_time;
 
  for(client = q_front(tabletennis->clients_to_ping);
 
      client && client->tabletennis_client.time_next_check < time_now.tv_sec;
 
      client = q_front(tabletennis->clients_to_ping))
 
    {
 
      q_dequeue(tabletennis->clients_to_ping);
 

	
 
      /* use time_next_check as the ping data */
 
      req_len = distren_request_poing(&req, &req_data, 1, &time_next_check, sizeof(time_next_check));
 
      distren_request_poing(&req, &req_data, 1, &time_next_check, sizeof(time_next_check));
 
      distrend_client_write_request(client, req, req_data);
 
      distren_request_free_with_data(req, req_data);
 

	
 
      client->tabletennis_client.state = TABLETENNIS_NEED_PONG;
 

	
 
      client->tabletennis_client.time_next_check = time_next_check;
0 comments (0 inline, 0 general)