Пример #1
0
int nt_stat(const char *filename, struct stat *stbuf) {

    // stat hangs on server name
    // Use any  directory, since the info in stat means %$!* on
    // windows anyway.
    // -amol 5/28/97
    /* is server or share */
    if (is_server(filename,0)  || is_server(filename,1) ||
            (*(filename+1) && *(filename+1) == ':' && !*(filename+2)) ) {
        return _stat("C:/",(struct _stat *)stbuf);
    }
    else  {
        char *last = (char*)filename + strlen(filename) -1;
        int rc = 0;
        BOOL lastslash = (*last == '/');
        if(lastslash)
        {
            *last = 0;
        }
        rc =  _stat(filename,(struct _stat *)stbuf);
        if(lastslash)
        {
            *last = '/';
        }
        return rc;
    }
}
Пример #2
0
/**************************************************************************
  write wrapper function -vasc
**************************************************************************/
static int write_socket_data(struct connection *pc,
			     struct socket_packet_buffer *buf, int limit)
{
  int start, nput, nblock;

  if (is_server() && pc->server.is_closing) {
    return 0;
  }

  for (start=0; buf->ndata-start>limit;) {
    fd_set writefs, exceptfs;
    struct timeval tv;

    FC_FD_ZERO(&writefs);
    FC_FD_ZERO(&exceptfs);
    FD_SET(pc->sock, &writefs);
    FD_SET(pc->sock, &exceptfs);

    tv.tv_sec = 0; tv.tv_usec = 0;

    if (fc_select(pc->sock+1, NULL, &writefs, &exceptfs, &tv) <= 0) {
      if (errno != EINTR) {
	break;
      } else {
	/* EINTR can happen sometimes, especially when compiling with -pg.
	 * Generally we just want to run select again. */
	continue;
      }
    }

    if (FD_ISSET(pc->sock, &exceptfs)) {
      connection_close(pc, _("network exception"));
      return -1;
    }

    if (FD_ISSET(pc->sock, &writefs)) {
      nblock=MIN(buf->ndata-start, MAX_LEN_PACKET);
      log_debug("trying to write %d limit=%d", nblock, limit);
      if((nput=fc_writesocket(pc->sock, 
			      (const char *)buf->data+start, nblock)) == -1) {
#ifdef NONBLOCKING_SOCKETS
	if (errno == EWOULDBLOCK || errno == EAGAIN) {
	  break;
	}
#endif
        connection_close(pc, _("lagging connection"));
        return -1;
      }
      start += nput;
    }
  }

  if (start > 0) {
    buf->ndata -= start;
    memmove(buf->data, buf->data+start, buf->ndata);
    pc->last_write = timer_renew(pc->last_write, TIMER_USER, TIMER_ACTIVE);
    timer_start(pc->last_write);
  }
  return 0;
}
Пример #3
0
ana_component::~ana_component( )
{
    if ( is_server() )
        delete server();
    else
        delete client();
}
Пример #4
0
/****************************************************************************
  Write data to socket. Return TRUE on success.
****************************************************************************/
bool connection_send_data(struct connection *pconn,
                          const unsigned char *data, int len)
{
  if (NULL == pconn
      || !pconn->used
      || (is_server() && pconn->server.is_closing)) {
    return TRUE;
  }

  pconn->statistics.bytes_send += len;
  if (0 < pconn->send_buffer->do_buffer_sends) {
    flush_connection_send_buffer_packets(pconn);
    if (!add_connection_data(pconn, data, len)) {
      log_verbose("cut connection %s due to huge send buffer (1)",
                  conn_description(pconn));
      return FALSE;
    }
    flush_connection_send_buffer_packets(pconn);
  } else {
    flush_connection_send_buffer_all(pconn);
    if (!add_connection_data(pconn, data, len)) {
      log_verbose("cut connection %s due to huge send buffer (2)",
                  conn_description(pconn));
      return FALSE;
    }
    flush_connection_send_buffer_all(pconn);
  }
  return TRUE;
}
Пример #5
0
bool ConfigurableRankDistribution::is_local_worker_to_communicate(int rank){
	if (is_server(rank))
		return false;
	if (rank == 0)
		return true;
	if (is_server_vector_[rank-1] == true)	// If previous rank is a server
		return true;
	return false;
}
Пример #6
0
struct net_route *
get_route(struct net_domain *_domain, const struct sockaddr *address)
{
	if (is_server(address)) {
		// to the server
		return &sServerContext.route;
	}

	return &sClientContext.route;
}
Пример #7
0
static gboolean
check_autojoin_channels (server * serv)
{
    char *po;
    session *sess;
    GSList *list = sess_list;
    int i = 0;
    GSList *channels, *keys;

    /* shouldnt really happen, the io tag is destroyed in server.c */
    if (!is_server (serv))
        return FALSE;

    /* send auto join list */
    if (serv->autojoin)
    {
        joinlist_split (serv->autojoin, &channels, &keys);
        serv->p_join_list (serv, channels, keys);
        joinlist_free (channels, keys);

        free (serv->autojoin);
        serv->autojoin = NULL;
    }

    /* this is really only for re-connects when you
     * join channels not in the auto-join list. */
    while (list)
    {
        sess = list->data;
        if (sess->server == serv)
        {
            if (sess->willjoinchannel[0] != 0)
            {
                strcpy (sess->waitchannel, sess->willjoinchannel);
                sess->willjoinchannel[0] = 0;
                serv->p_join (serv, sess->waitchannel,
                              sess->channelkey);
                po = strchr (sess->waitchannel, ',');
                if (po)
                    *po = 0;
                po = strchr (sess->waitchannel, ' ');
                if (po)
                    *po = 0;
                i++;
            }
        }
        list = list->next;
    }
    serv->joindelay_tag = 0;
    fe_server_event (serv, FE_SE_LOGGEDIN, i);
    return FALSE;
}
Пример #8
0
bool disconnect(connection s)
{
	if(s == 0) {
		while(sockets.empty() == false) {
			assert(sockets.back() != 0);
			while(disconnect(sockets.back()) == false) {
				SDL_Delay(1);
			}
		}
		return true;
	}
	if (!is_server()) last_ping = 0;

	const connection_map::iterator info = connections.find(s);
	if(info != connections.end()) {
		if (info->second.sock == server_socket)
		{
			return true;
		}
		if (!network_worker_pool::close_socket(info->second.sock)) {
			return false;
		}
	}

	bad_sockets.erase(s);

	std::deque<network::connection>::iterator dqi = std::find(disconnection_queue.begin(),disconnection_queue.end(),s);
	if(dqi != disconnection_queue.end()) {
		disconnection_queue.erase(dqi);
	}

	const sockets_list::iterator i = std::find(sockets.begin(),sockets.end(),s);
	if(i != sockets.end()) {
		sockets.erase(i);

		const TCPsocket sock = get_socket(s);

		waiting_sockets.erase(s);
		SDLNet_TCP_DelSocket(socket_set,sock);
		SDLNet_TCP_Close(sock);

		remove_connection(s);
	} else {
		if(sockets.size() == 1) {
			DBG_NW << "valid socket: " << static_cast<int>(*sockets.begin()) << "\n";
		}
	}

	return true;
}
void kill_corrupt()
{
	if (local_type() != internal_type)
	{
    log_client_abort(error_client_type);
	isolate_client();
	}

	if (is_server())
	{
    log_client_abort(error_client_server);
	isolate_client();
	}
}
Пример #10
0
/****************************************************************************
  Turn off buffering if internal counter of number of times buffering
  was turned on falls to zero, to handle nested buffer/unbuffer pairs.
  When counter is zero, flush any pending data.
***************************************************************************/
void connection_do_unbuffer(struct connection *pc)
{
  if (NULL == pc || !pc->used || (is_server() && pc->server.is_closing)) {
    return;
  }

  pc->send_buffer->do_buffer_sends--;
  if (0 > pc->send_buffer->do_buffer_sends) {
    log_error("Too many calls to unbuffer %s!", pc->username);
    pc->send_buffer->do_buffer_sends = 0;
  }

  if (0 == pc->send_buffer->do_buffer_sends) {
    flush_connection_send_buffer_all(pc);
  }
}
Пример #11
0
/**
 * Fetch the next waiting client socket from the server
 * @param sock
 * @return
 */
sock_result_t socket_accept(sock_handle_t sock)
{
    sock_result_t result = SOCKET_INVALID;
    socket_t* socket = from_handle(sock);
    if (is_open(socket) && is_server(socket)) {
        std::lock_guard<socket_t> lk(*socket);
        tcp_server_t* server = socket->s.tcp_server;
        tcp_server_client_t* client = server->next_accept();
        if (client) {
            socket_t* socket = new socket_t();
            socket->set_client(client);
            {
                SocketListLock lock(list_for(socket));
                add_socket(socket);
            }
            result = (sock_result_t)socket;
        }
    }
    return result;
}
Пример #12
0
/* @brief Parses the LSA file and generates a hashtable of IP's and neighbors
 */
void parse_file(){
	FILE* fp = fopen(lsa_file, "r");
	if(fp == NULL) return;

	char* 	line = NULL;
	size_t 	len = 0;
	ssize_t read;
	char	IP[MAX_IP_SIZE + 1];
	memset(IP, 0, MAX_IP_SIZE + 1);
	int 	seq;
	char*	nbors;
	lsa*	temp;
	lsa*	find;

	while((read = getline(&line, &len, fp)) != -1){
		nbors = malloc(MAX_IP_SIZE * (get_comma_count(line) + 1));
		sscanf(line, "%s %d %s", IP, &seq, nbors);
		temp = calloc(1, sizeof(lsa));
		strcpy(temp->sender, IP);
		temp->seq = seq;
		is_server(IP, temp);
		parse_nbors(temp, nbors);
		HASH_FIND_STR(lsa_hash, IP, find);
		if(find == NULL){
			HASH_ADD_STR(lsa_hash, sender, temp);
		} else {
			if(find->seq < temp->seq){
				for(int i = 0; i < (int)find->num_nbors; i++){
					free(find->nbors[i]);
				}
				free(find->nbors);
				find->nbors = temp->nbors;
				find->num_nbors = temp->num_nbors;
				find->seq = temp->seq;
			}
		}
		free(nbors);
	}
	free(line);
	fclose(fp);
}
Пример #13
0
/****************************************************************************
  Add data to send to the connection.
****************************************************************************/
static bool add_connection_data(struct connection *pconn,
                                const unsigned char *data, int len)
{
  struct socket_packet_buffer *buf;

  if (NULL == pconn
      || !pconn->used
      || (is_server() && pconn->server.is_closing)) {
    return TRUE;
  }

  buf = pconn->send_buffer;
  log_debug("add %d bytes to %d (space =%d)", len, buf->ndata, buf->nsize);
  if (!buffer_ensure_free_extra_space(buf, len)) {
    connection_close(pconn, _("buffer overflow"));
    return FALSE;
  }

  memcpy(buf->data + buf->ndata, data, len);
  buf->ndata += len;
  return TRUE;
}
Пример #14
0
static void
joind_ok_cb (GtkWidget *ok, server *serv)
{
	if (!is_server (serv))
	{
		gtk_widget_destroy (gtk_widget_get_toplevel (ok));
		return;
	}

	/* do nothing */
	if (GTK_TOGGLE_BUTTON (serv->gui->joind_radio1)->active)
		goto xit;

	/* join specific channel */
	if (GTK_TOGGLE_BUTTON (serv->gui->joind_radio2)->active)
	{
		char *text = GTK_ENTRY (serv->gui->joind_entry)->text;
		if (strlen (text) < 2)
		{
			fe_message (_("Channel name too short, try again."), FE_MSG_ERROR);
			return;
		}
		serv->p_join (serv, text, "");
		goto xit;
	}

	/* channel list */
	chanlist_opengui (serv, TRUE);

xit:
	prefs.gui_join_dialog = 0;
	if (GTK_TOGGLE_BUTTON (serv->gui->joind_check)->active)
		prefs.gui_join_dialog = 1;

	gtk_widget_destroy (serv->gui->joind_win);
	serv->gui->joind_win = NULL;
}
Пример #15
0
static gboolean
check_autojoin_channels (server *serv)
{
	int i = 0;
	session *sess;
	GSList *list = sess_list;
	GSList *sess_channels = NULL;			/* joined channels that are not in the favorites list */
	favchannel *fav;

	/* shouldn't really happen, the io tag is destroyed in server.c */
	if (!is_server (serv))
	{
		return FALSE;
	}

	/* If there's a session (i.e. this is a reconnect), autojoin to everything that was open previously. */
	while (list)
	{
		sess = list->data;

		if (sess->server == serv)
		{
			if (sess->willjoinchannel[0] != 0)
			{
				strcpy (sess->waitchannel, sess->willjoinchannel);
				sess->willjoinchannel[0] = 0;

				fav = servlist_favchan_find (serv->network, sess->waitchannel, NULL);	/* Is this channel in our favorites? */

				/* session->channelkey is initially unset for channels joined from the favorites. You have to fill them up manually from favorites settings. */
				if (fav)
				{
					/* session->channelkey is set if there was a key change during the session. In that case, use the session key, not the one from favorites. */
					if (fav->key && !strlen (sess->channelkey))
					{
						safe_strcpy (sess->channelkey, fav->key, sizeof (sess->channelkey));
					}
				}

				/* for easier checks, ensure that favchannel->key is just NULL when session->channelkey is empty i.e. '' */
				if (strlen (sess->channelkey))
				{
					sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, sess->channelkey);
				}
				else
				{
					sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, NULL);
				}
				i++;
			}
		}

		list = list->next;
	}

	if (sess_channels)
	{
		serv->p_join_list (serv, sess_channels);
		g_slist_free_full (sess_channels, (GDestroyNotify) servlist_favchan_free);
	}
	else
	{
		/* If there's no session, just autojoin to favorites. */
		if (serv->favlist)
		{
			serv->p_join_list (serv, serv->favlist);
			i++;

			/* FIXME this is not going to work and is not needed either. server_free() does the job already. */
			/* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */
		}
	}

	serv->joindelay_tag = 0;
	fe_server_event (serv, FE_SE_LOGGEDIN, i);
	return FALSE;
}
Пример #16
0
/**************************************************************************
presult indicates if there is more packets in the cache. We return result
instead of just testing if the returning package is NULL as we sometimes
return a NULL packet even if everything is OK (receive_packet_goto_route).
**************************************************************************/
void *get_packet_from_connection(struct connection *pc,
				 enum packet_type *ptype, bool * presult)
{
  int len_read;
  int whole_packet_len;
  struct {
    enum packet_type type;
    int itype;
  } utype;
  struct data_in din;
#ifdef USE_COMPRESSION
  bool compressed_packet = FALSE;
  int header_size = 0;
#endif

  *presult = FALSE;

  if (!pc->used) {
    return NULL;		/* connection was closed, stop reading */
  }
  
  if (pc->buffer->ndata < 3) {
    return NULL;           /* length and type not read */
  }

  dio_input_init(&din, pc->buffer->data, pc->buffer->ndata);
  dio_get_uint16(&din, &len_read);

  /* The non-compressed case */
  whole_packet_len = len_read;

#ifdef USE_COMPRESSION
  if (len_read == JUMBO_SIZE) {
    compressed_packet = TRUE;
    header_size = 6;
    if (dio_input_remaining(&din) >= 4) {
      dio_get_uint32(&din, &whole_packet_len);
      log_compress("COMPRESS: got a jumbo packet of size %d",
                   whole_packet_len);
    } else {
      /* to return NULL below */
      whole_packet_len = 6;
    }
  } else if (len_read >= COMPRESSION_BORDER) {
    compressed_packet = TRUE;
    header_size = 2;
    whole_packet_len = len_read - COMPRESSION_BORDER;
    log_compress("COMPRESS: got a normal packet of size %d",
                 whole_packet_len);
  }
#endif

  if ((unsigned)whole_packet_len > pc->buffer->ndata) {
    return NULL;		/* not all data has been read */
  }

#ifdef USE_COMPRESSION
  if (compressed_packet) {
    uLong compressed_size = whole_packet_len - header_size;
    /* 
     * We don't know the decompressed size. We assume a bad case
     * here: an expansion by an factor of 100. 
     */
    unsigned long int decompressed_size = 100 * compressed_size;
    void *decompressed = fc_malloc(decompressed_size);
    int error;
    struct socket_packet_buffer *buffer = pc->buffer;
    
    error =
	uncompress(decompressed, &decompressed_size,
		   ADD_TO_POINTER(buffer->data, header_size), 
		   compressed_size);
    if (error != Z_OK) {
      log_verbose("Uncompressing of the packet stream failed. "
                  "The connection will be closed now.");
      connection_close(pc, _("decoding error"));
      return NULL;
    }

    buffer->ndata -= whole_packet_len;
    /* 
     * Remove the packet with the compressed data and shift all the
     * remaining data to the front. 
     */
    memmove(buffer->data, buffer->data + whole_packet_len, buffer->ndata);

    if (buffer->ndata + decompressed_size > buffer->nsize) {
      buffer->nsize += decompressed_size;
      buffer->data = fc_realloc(buffer->data, buffer->nsize);
    }

    /*
     * Make place for the uncompressed data by moving the remaining
     * data.
     */
    memmove(buffer->data + decompressed_size, buffer->data, buffer->ndata);

    /* 
     * Copy the uncompressed data.
     */
    memcpy(buffer->data, decompressed, decompressed_size);

    free(decompressed);

    buffer->ndata += decompressed_size;
    
    log_compress("COMPRESS: decompressed %ld into %ld",
                 compressed_size, decompressed_size);

    return get_packet_from_connection(pc, ptype, presult);
  }
#endif

  /*
   * At this point the packet is a plain uncompressed one. These have
   * to have to be at least 3 bytes in size.
   */
  if (whole_packet_len < 3) {
    log_verbose("The packet stream is corrupt. The connection "
                "will be closed now.");
    connection_close(pc, _("decoding error"));
    return NULL;
  }

  dio_get_uint8(&din, &utype.itype);

  utype.type = utype.itype;

  log_packet("got packet type=(%s)%d len=%d from %s",
             packet_name(utype.type), utype.itype, whole_packet_len,
             is_server() ? pc->username : "******");

  *ptype = utype.type;
  *presult = TRUE;

  if (pc->incoming_packet_notify) {
    pc->incoming_packet_notify(pc, utype.type, whole_packet_len);
  }

#if PACKET_SIZE_STATISTICS 
  {
    static struct {
      int counter;
      int size;
    } packets_stats[PACKET_LAST];
    static int packet_counter = 0;

    int packet_type = utype.itype;
    int size = whole_packet_len;

    if (!packet_counter) {
      int i;

      for (i = 0; i < PACKET_LAST; i++) {
	packets_stats[i].counter = 0;
	packets_stats[i].size = 0;
      }
    }

    packets_stats[packet_type].counter++;
    packets_stats[packet_type].size += size;

    packet_counter++;
    if (packet_counter % 100 == 0) {
      int i, sum = 0;

      log_test("Received packets:");
      for (i = 0; i < PACKET_LAST; i++) {
	if (packets_stats[i].counter == 0)
	  continue;
	sum += packets_stats[i].size;
        log_test("  [%-25.25s %3d]: %6d packets; %8d bytes total; "
                 "%5d bytes/packet average",
                 packet_name(i), i, packets_stats[i].counter,
                 packets_stats[i].size,
                 packets_stats[i].size / packets_stats[i].counter);
      }
      log_test("received %d bytes in %d packets;average size "
               "per packet %d bytes",
               sum, packet_counter, sum / packet_counter);
    }
  }
#endif
  return get_packet_from_connection_helper(pc, utype.type);
}
Пример #17
0
/**************************************************************************
  It returns the request id of the outgoing packet (or 0 if is_server()).
**************************************************************************/
int send_packet_data(struct connection *pc, unsigned char *data, int len)
{
  /* default for the server */
  int result = 0;

  log_packet("sending packet type=%s(%d) len=%d to %s",
             packet_name(data[2]), data[2], len,
             is_server() ? pc->username : "******");

  if (!is_server()) {
    pc->client.last_request_id_used =
        get_next_request_id(pc->client.last_request_id_used);
    result = pc->client.last_request_id_used;
    log_packet("sending request %d", result);
  }

  if (pc->outgoing_packet_notify) {
    pc->outgoing_packet_notify(pc, data[2], len, result);
  }

#ifdef USE_COMPRESSION
  if (TRUE) {
    int packet_type;
    int size = len;

    packet_type = data[2];
    if (conn_compression_frozen(pc)) {
      size_t old_size = pc->compression.queue.size;

      byte_vector_reserve(&pc->compression.queue, old_size + len);
      memcpy(pc->compression.queue.p + old_size, data, len);
      log_compress2("COMPRESS: putting %s into the queue",
                    packet_name(packet_type));
      if (MAX_LEN_BUFFER < byte_vector_size(&pc->compression.queue)) {
        log_compress2("COMPRESS: huge queue, forcing to flush (%lu/%lu)",
                      (long unsigned)
                      byte_vector_size(&pc->compression.queue),
                      (long unsigned) MAX_LEN_BUFFER);
        if (!conn_compression_flush(pc)) {
          return -1;
        }
        byte_vector_reserve(&pc->compression.queue, 0);
      }
    } else {
      stat_size_alone += size;
      log_compress("COMPRESS: sending %s alone (%d bytes total)",
                   packet_name(packet_type), stat_size_alone);
      connection_send_data(pc, data, len);
    }

    log_compress2("COMPRESS: STATS: alone=%d compression-expand=%d "
                  "compression (before/after) = %d/%d",
                  stat_size_alone, stat_size_no_compression,
                  stat_size_uncompressed, stat_size_compressed);
  }
#else
  connection_send_data(pc, data, len);
#endif

#if PACKET_SIZE_STATISTICS
  {
    static struct {
      int counter;
      int size;
    } packets_stats[PACKET_LAST];
    static int packet_counter = 0;
    static int last_start_turn_seen = -1;
    static bool start_turn_seen = FALSE;

    int packet_type = data[2];
    int size = len;
    bool print = FALSE;
    bool clear = FALSE;

    if (!packet_counter) {
      int i;

      for (i = 0; i < PACKET_LAST; i++) {
	packets_stats[i].counter = 0;
	packets_stats[i].size = 0;
      }
    }

    packets_stats[packet_type].counter++;
    packets_stats[packet_type].size += size;

    packet_counter++;
    if (packet_type == PACKET_START_TURN
	&& last_start_turn_seen != game.turn) {
	start_turn_seen=TRUE;
      last_start_turn_seen = game.turn;
    }

    if ((packet_type ==
	 PACKET_PROCESSING_FINISHED || packet_type == PACKET_THAW_HINT)
	&& start_turn_seen) {
      start_turn_seen = FALSE;
      print = TRUE;
      clear = TRUE;
    }

    if(print) {
      int i, sum = 0;
#define log_ll log_debug

#if PACKET_SIZE_STATISTICS == 2
      delta_stats_report();
#endif
      log_ll("Transmitted packets:");
      log_ll("%8s %8s %8s %s", "Packets", "Bytes", "Byt/Pac", "Name");

      for (i = 0; i < PACKET_LAST; i++) {
	if (packets_stats[i].counter == 0) {
	  continue;
	}
	sum += packets_stats[i].size;
        log_ll("%8d %8d %8d %s(%i)",
               packets_stats[i].counter, packets_stats[i].size,
               packets_stats[i].size / packets_stats[i].counter,
               packet_name(i),i);
      }
      log_test("turn=%d; transmitted %d bytes in %d packets;average size "
               "per packet %d bytes", game.turn, sum, packet_counter,
               sum / packet_counter);
      log_test("turn=%d; transmitted %d bytes", game.turn,
               pc->statistics.bytes_send);
    }
    if (clear) {
      int i;

      for (i = 0; i < PACKET_LAST; i++) {
	packets_stats[i].counter = 0;
	packets_stats[i].size = 0;
      }
      packet_counter = 0;
      pc->statistics.bytes_send = 0;
      delta_stats_reset();
    }
  }
#undef log_ll
#endif /* PACKET_SIZE_STATISTICS */

  return result;
}
Пример #18
0
inline tcp_server_t* server(socket_t* socket) { return is_server(socket) ? socket->s.tcp_server : NULL; }
Пример #19
0
static void
joind_destroy_cb (GtkWidget *win, server *serv)
{
	if (is_server (serv))
		serv->gui->joind_win = NULL;
}
Пример #20
0
/**************************************************************************
  It returns the request id of the outgoing packet (or 0 if is_server()).
**************************************************************************/
int send_packet_data(struct connection *pc, unsigned char *data, int len,
                     enum packet_type packet_type)
{
  /* default for the server */
  int result = 0;


  log_packet("sending packet type=%s(%d) len=%d to %s",
             packet_name(packet_type), packet_type, len,
             is_server() ? pc->username : "******");

  if (!is_server()) {
    pc->client.last_request_id_used =
        get_next_request_id(pc->client.last_request_id_used);
    result = pc->client.last_request_id_used;
    log_packet("sending request %d", result);
  }

  if (pc->outgoing_packet_notify) {
    pc->outgoing_packet_notify(pc, packet_type, len, result);
  }

#ifdef USE_COMPRESSION
  if (TRUE) {
    int size = len;

    if (conn_compression_frozen(pc)) {
      size_t old_size;

      /* Keep this a decent amount less than MAX_LEN_BUFFER to avoid the
       * (remote) possibility of trying to dump MAX_LEN_BUFFER to the
       * network in one go */
#define MAX_LEN_COMPRESS_QUEUE (MAX_LEN_BUFFER/2)
      FC_STATIC_ASSERT(MAX_LEN_COMPRESS_QUEUE < MAX_LEN_BUFFER,
                       compress_queue_maxlen_too_big);

      /* If this packet would cause us to overfill the queue, flush
       * everything that's in there already before queuing this one */
      if (MAX_LEN_COMPRESS_QUEUE
          < byte_vector_size(&pc->compression.queue) + len) {
        log_compress2("COMPRESS: huge queue, forcing to flush (%lu/%lu)",
                      (long unsigned)
                      byte_vector_size(&pc->compression.queue),
                      (long unsigned) MAX_LEN_COMPRESS_QUEUE);
        if (!conn_compression_flush(pc)) {
          return -1;
        }
        byte_vector_reserve(&pc->compression.queue, 0);
      }

      old_size = byte_vector_size(&pc->compression.queue);
      byte_vector_reserve(&pc->compression.queue, old_size + len);
      memcpy(pc->compression.queue.p + old_size, data, len);
      log_compress2("COMPRESS: putting %s into the queue",
                    packet_name(packet_type));
    } else {
      stat_size_alone += size;
      log_compress("COMPRESS: sending %s alone (%d bytes total)",
                   packet_name(packet_type), stat_size_alone);
      connection_send_data(pc, data, len);
    }

    log_compress2("COMPRESS: STATS: alone=%d compression-expand=%d "
                  "compression (before/after) = %d/%d",
                  stat_size_alone, stat_size_no_compression,
                  stat_size_uncompressed, stat_size_compressed);
  }
#else  /* USE_COMPRESSION */
  connection_send_data(pc, data, len);
#endif /* USE_COMPRESSION */

#if PACKET_SIZE_STATISTICS
  {
    static struct {
      int counter;
      int size;
    } packets_stats[PACKET_LAST];
    static int packet_counter = 0;
    static int last_start_turn_seen = -1;
    static bool start_turn_seen = FALSE;

    int size = len;
    bool print = FALSE;
    bool clear = FALSE;

    if (!packet_counter) {
      int i;

      for (i = 0; i < PACKET_LAST; i++) {
	packets_stats[i].counter = 0;
	packets_stats[i].size = 0;
      }
    }

    packets_stats[packet_type].counter++;
    packets_stats[packet_type].size += size;

    packet_counter++;
    if (packet_type == PACKET_START_TURN
	&& last_start_turn_seen != game.turn) {
	start_turn_seen=TRUE;
      last_start_turn_seen = game.turn;
    }

    if ((packet_type ==
	 PACKET_PROCESSING_FINISHED || packet_type == PACKET_THAW_HINT)
	&& start_turn_seen) {
      start_turn_seen = FALSE;
      print = TRUE;
      clear = TRUE;
    }

    if(print) {
      int i, sum = 0;
#define log_ll log_debug

#if PACKET_SIZE_STATISTICS == 2
      delta_stats_report();
#endif
      log_ll("Transmitted packets:");
      log_ll("%8s %8s %8s %s", "Packets", "Bytes", "Byt/Pac", "Name");

      for (i = 0; i < PACKET_LAST; i++) {
	if (packets_stats[i].counter == 0) {
	  continue;
	}
	sum += packets_stats[i].size;
        log_ll("%8d %8d %8d %s(%i)",
               packets_stats[i].counter, packets_stats[i].size,
               packets_stats[i].size / packets_stats[i].counter,
               packet_name(i),i);
      }
      log_test("turn=%d; transmitted %d bytes in %d packets;average size "
               "per packet %d bytes", game.turn, sum, packet_counter,
               sum / packet_counter);
      log_test("turn=%d; transmitted %d bytes", game.turn,
               pc->statistics.bytes_send);
    }
    if (clear) {
      int i;

      for (i = 0; i < PACKET_LAST; i++) {
	packets_stats[i].counter = 0;
	packets_stats[i].size = 0;
      }
      packet_counter = 0;
      pc->statistics.bytes_send = 0;
      delta_stats_reset();
    }
  }
#undef log_ll
#endif /* PACKET_SIZE_STATISTICS */

  return result;
}
Пример #21
0
status_t
domain_receive_data(net_buffer *buffer)
{
	static bigtime_t lastTime = 0;

	uint32 packetNumber = atomic_add(&sPacketNumber, 1);

	bool drop = false;
	if (sDropList.find(packetNumber) != sDropList.end()
		|| (sRandomDrop > 0.0 && (1.0 * rand() / RAND_MAX) > sRandomDrop))
		drop = true;

	if (!drop && (sRoundTripTime > 0 || sRandomRoundTrip || sIncreasingRoundTrip)) {
		bigtime_t add = 0;
		if (sRandomRoundTrip)
			add = (bigtime_t)(1.0 * rand() / RAND_MAX * 500000) - 250000;
		if (sIncreasingRoundTrip)
			sRoundTripTime += (bigtime_t)(1.0 * rand() / RAND_MAX * 150000);

		snooze(sRoundTripTime / 2 + add);
	}

	if (sTCPDump) {
		NetBufferHeaderReader<tcp_header> bufferHeader(buffer);
		if (bufferHeader.Status() < B_OK)
			return bufferHeader.Status();

		tcp_header &header = bufferHeader.Data();

		bigtime_t now = system_time();
		if (lastTime == 0)
			lastTime = now;

		printf("\33[0m% 3ld %8.6f (%8.6f) ", packetNumber, (now - sStartTime) / 1000000.0,
			(now - lastTime) / 1000000.0);
		lastTime = now;

		if (is_server((sockaddr *)buffer->source))
			printf("\33[31mserver > client: ");
		else
			printf("client > server: ");

		int32 length = buffer->size - header.HeaderLength();

		if ((header.flags & TCP_FLAG_PUSH) != 0)
			putchar('P');
		if ((header.flags & TCP_FLAG_SYNCHRONIZE) != 0)
			putchar('S');
		if ((header.flags & TCP_FLAG_FINISH) != 0)
			putchar('F');
		if ((header.flags & TCP_FLAG_RESET) != 0)
			putchar('R');
		if ((header.flags
			& (TCP_FLAG_SYNCHRONIZE | TCP_FLAG_FINISH | TCP_FLAG_PUSH | TCP_FLAG_RESET)) == 0)
			putchar('.');

		printf(" %lu:%lu (%lu)", header.Sequence(), header.Sequence() + length, length);
		if ((header.flags & TCP_FLAG_ACKNOWLEDGE) != 0)
			printf(" ack %lu", header.Acknowledge());

		printf(" win %u", header.AdvertisedWindow());

		if (header.HeaderLength() > sizeof(tcp_header)) {
			int32 size = header.HeaderLength() - sizeof(tcp_header);

			tcp_option *option;
			uint8 optionsBuffer[1024];
			if (gBufferModule->direct_access(buffer, sizeof(tcp_header),
					size, (void **)&option) != B_OK) {
				if (size > 1024) {
					printf("options too large to take into account (%ld bytes)\n", size);
					size = 1024;
				}

				gBufferModule->read(buffer, sizeof(tcp_header), optionsBuffer, size);
				option = (tcp_option *)optionsBuffer;
			}

			while (size > 0) {
				uint32 length = 1;
				switch (option->kind) {
					case TCP_OPTION_END:
					case TCP_OPTION_NOP:
						break;
					case TCP_OPTION_MAX_SEGMENT_SIZE:
						printf(" <mss %u>", ntohs(option->max_segment_size));
						length = 4;
						break;
					case TCP_OPTION_WINDOW_SHIFT:
						printf(" <ws %u>", option->window_shift);
						length = 3;
						break;
					case TCP_OPTION_TIMESTAMP:
						printf(" <ts %lu:%lu>", option->timestamp.value, option->timestamp.reply);
						length = 10;
						break;

					default:
						length = option->length;
						// make sure we don't end up in an endless loop
						if (length == 0)
							size = 0;
						break;
				}

				size -= length;
				option = (tcp_option *)((uint8 *)option + length);
			}
		}

		if (drop)
			printf(" <DROPPED>");
		printf("\33[0m\n");
	} else if (drop)
		printf("<**** DROPPED %ld ****>\n", packetNumber);

	if (drop) {
		gNetBufferModule.free(buffer);
		return B_OK;
	}

	return gTCPModule->receive_data(buffer);
}
Пример #22
0
static void
close_rawlog (GtkWidget *wid, server *serv)
{
	if (is_server (serv))
		serv->gui->rawlog_window = 0;
}
Пример #23
0
static void
chanlist_closegui (GtkWidget *wid, server *serv)
{
	if (is_server (serv))
		serv->gui->chanlist_window = NULL;
}