Games-FrozenBubble
view release on metacpan or search on metacpan
server/net.c_tmp view on Meta::CPAN
|| (incoming_data_buffers_count[fd] > 0 && incoming_data_buffers[fd][incoming_data_buffers_count[fd]-1] == '\n'))) {
char buf[INCOMING_DATA_BUFSIZE];
ssize_t len;
ssize_t offset = incoming_data_buffers_count[fd];
incoming_data_buffers_count[fd] = 0;
memcpy(buf, incoming_data_buffers[fd], offset);
len = recv(fd, buf + offset, INCOMING_DATA_BUFSIZE - 1 - offset, MSG_DONTWAIT);
if (len == -1 && errno != EAGAIN) {
l2(OUTPUT_TYPE_DEBUG, "[%d] System error on recv: %s", fd, strerror(errno));
conn_terminated(fd, "system error on recv");
return;
} else if (len == 0) {
conn_terminated(fd, "peer shutdown");
return;
} else {
char* ptr;
char* eol;
if (len == -1)
len = 0;
last_data_in[fd] = current_time;
if (minute_for_talk_flood[fd] != current_time/60) {
minute_for_talk_flood[fd] = current_time/60;
amount_talk_flood[fd] = 0;
}
len += offset;
// If we don't have a newline, it means we are seeing a partial send. Buffer
// them, since we can't synchronously wait for newline now or else we'd offer a
// nice easy shot for DOS (and beside, this would slow down the whole rest).
if (buf[len-1] != '\n') {
if (len == INCOMING_DATA_BUFSIZE - 1) {
send_line_log_push(fd, fl_client_nolf);
conn_terminated(fd, "too much data without LF");
return;
}
l2(OUTPUT_TYPE_DEBUG, "[%d] buffering %zd bytes (this is normal)", fd, len);
memcpy(incoming_data_buffers[fd], buf, len);
incoming_data_buffers_count[fd] = len;
return;
}
/* string operations will need a NULL conn_terminated string */
buf[len] = '\0';
ptr = buf;
while (1) {
if (!(eol = strchr(ptr, '\n'))) {
// the bad bad guy sent a 0 byte before the \n
if (!prio)
send_line_log_push(fd, fl_client_nulbyte);
conn_terminated(fd, "NUL byte before newline");
return;
}
if (prio) {
// prio e.g. in game; we split messages because p and ! must be treated specially (see game::process_msg_prio)
process_msg_prio(fd, ptr, eol - ptr + 1);
len -= eol - ptr + 1;
if (len == 0) {
prio_processed = 1;
break;
}
ptr = eol + 1;
} else {
eol[0] = '\0';
if (process_msg(fd, ptr)) {
conn_terminated(fd, "process_msg said to shutdown this connection");
return;
}
// process_msg > talk (flooding) > conn_terminated
if (interrupt_loop_processing)
return;
if (eol + 1 - ptr < len) {
ssize_t remaining = len - (eol + 1 - ptr);
l2(OUTPUT_TYPE_DEBUG, "multiple non-prio messages for %d, buffering (%zd bytes)", fd, remaining);
memcpy(incoming_data_buffers[fd], eol + 1, remaining);
incoming_data_buffers_count[fd] = remaining;
need_another_run = 1;
}
/* must handle only one message, because we might have multiple and subsequent might need to be
treated as prio message if the one before is about starting the game */
break;
}
}
}
return;
}
if (prio) {
// 5 seconds is in game gracetime after which player is kicked out
if (current_time - last_data_in[fd] > 5) {
conn_terminated(fd, "no activity within gracetime (during game, gracetime of 5 secs)");
}
} else {
if (current_time - last_data_in[fd] > gracetime) {
send_line_log_push(fd, fl_client_noactivity);
conn_terminated(fd, "no activity within gracetime (not during game)");
}
}
}
static void handle_incoming_data(gpointer data, gpointer user_data)
{
handle_incoming_data_generic(data, user_data, 0);
}
static void handle_incoming_data_prio(gpointer data, gpointer user_data)
{
handle_incoming_data_generic(data, user_data, 1);
}
static void handle_udp_request(void)
{
static char ok_input_beginning_base[] = "FB/%d.";
static char * ok_input_beginning = NULL;
( run in 2.629 seconds using v1.01-cache-2.11-cpan-71847e10f99 )