static struct connection* connection_new(const char *evdev_path, const char *host_and_port) { struct connection* self; /* Allocate the new server object */ self = malloc(sizeof(struct connection)); assert(self != NULL); memset(self, 0, sizeof(struct connection)); if (evdev_init(&self->evdev, evdev_path) < 0) { connection_delete(self); return NULL; } connection_set_status_led(self, 0); connection_message(self, "Connecting to '%s'...", host_and_port); self->server = server_new(host_and_port); if (!self->server) { connection_delete(self); return NULL; } /* Tell the server about our device */ if (evdev_send_metadata(&self->evdev, self->server)) { connection_delete(self); return NULL; } connection_list_append(self); connection_message(self, "Connected"); connection_set_status_led(self, 1); return self; }
void cleanup(void) { int i; tims_print("Terminate\n"); terminate = 1; // close connection sockets for (i = 0; i < MAX_CONNECTIONS; i++) { if (conList[i].socket != -1) // socket opened connection_delete(&conList[i]); } // join watchdog thread if (init_flags & TIMS_ROUTER_WATCHDOG) { pthread_join(watchdogThread, NULL); tims_dbgdetail("watchdogThread joined\n"); init_flags &= ~TIMS_ROUTER_WATCHDOG; } // join connection threads for (i = 0; i < MAX_CONNECTIONS; i++) { if (conList[i].index != -1) { pthread_join(conList[i].conThread, NULL); tims_dbgdetail("connection thead[%d] joined\n", conList[i].index); } } // destroy send semaphore for (i = 0; i < MAX_CONNECTIONS; i++) { if (sem_flags & (1 << i) ) { sem_destroy(&conList[i].sendSem); tims_dbgdetail("sendSem[%i] destroyed\n",i); sem_flags &= ~(1 << i); } } if (init_flags & TIMS_ROUTER_SEM_LIST) { sem_destroy(&mbxListSem); tims_dbgdetail("mbxListSem destroyed \n"); init_flags &= ~TIMS_ROUTER_SEM_LIST; } if (tcpServerSocket != -1 ) { close(tcpServerSocket); tcpServerSocket = -1; tims_dbgdetail("tcpServerSocket closed\n"); } }
static void connection_list_poll(fd_set *fd_read) { struct connection *i, *next; i = connection_list_head; while (i) { next = i->next; if (connection_poll(i, fd_read)) connection_delete(i); i = next; } }
static void client_free(void *ctx) { struct connection *c = ctx; assert(c->client.client != NULL); if (c->autoreconnect && c->in_game) { log(2, "server disconnected, auto-reconnecting\n"); connection_speak_console(c, "uoproxy was disconnected, auto-reconnecting..."); connection_disconnect(c); connection_reconnect_delayed(c); } else { log(1, "server disconnected\n"); connection_delete(c); } }
static int client_packet(const void *data, size_t length, void *ctx) { struct connection *c = ctx; packet_action_t action; struct linked_server *ls; assert(c->client.client != NULL); action = handle_packet_from_server(server_packet_bindings, c, data, length); switch (action) { case PA_ACCEPT: if (!c->client.reconnecting) list_for_each_entry(ls, &c->servers, siblings) if (!ls->attaching && !ls->is_zombie) uo_server_send(ls->server, data, length); break; case PA_DROP: break; case PA_DISCONNECT: log(2, "aborting connection to server after packet 0x%x\n", *(const unsigned char*)data); log_hexdump(6, data, length); if (c->autoreconnect && c->in_game) { log(2, "auto-reconnecting\n"); connection_disconnect(c); connection_reconnect_delayed(c); } else { connection_delete(c); } return -1; case PA_DELETED: return -1; } return 0; }
// The watchdogTask sends a lifesign to every connected client. // Clients that don't respond will be disconnected void watchdog_task_proc(void *arg) { tims_msg_head lifesignMsg; int i; signal(SIGHUP, signal_handler); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); signal(SIGPIPE, signal_handler); tims_dbg("watchdog task: start\n"); tims_fillhead(&lifesignMsg, TIMS_MSG_ROUTER_GET_STATUS, 0, 0, 0, 0, 0, TIMS_HEADLEN); while (!terminate) { for (i = 0; i < MAX_CONNECTIONS; i++) { if (conList[i].socket >= 0) { conList[i].watchdog = 1; sndTcpTimsMsg(&conList[i], &lifesignMsg); } } tims_dbg("watchdog wait ...\n"); sleep(5); for (i = 0; i < MAX_CONNECTIONS; i++) { if ((conList[i].socket >= 0) && (conList[i].watchdog == 1)) { connection_delete(&conList[i]); tims_print("con[%02d]: Connection closed by watchdog\n", i); } } } tims_dbg("watchdog task: exit\n"); }
/* -------------------------------------------------------------------------- */ void *mpd_run(void *cookie) { time_t next_update, current; gboolean result; int retry_count = RETRY_INTERVAL; struct lcd_stuff_mpd mpd; /* default values */ mpd.lcd = (struct lcd_stuff *)cookie; mpd.mpd = NULL; mpd.error = 0; mpd.current_state = 0; mpd.song_displayed = false; mpd.current_song = NULL; mpd.stop_time = UINT_MAX; mpd.current_list = NULL; mpd.connection = NULL; mpd.timeout = 0; result = key_file_has_group(MODULE_NAME); if (!result) { report(RPT_INFO, "mpd disabled"); conf_dec_count(); return NULL; } if (!mpd_init(&mpd)) goto out; if (!mpd_init_connection(&mpd)) goto out_screen; if (!mpd_start_connection(&mpd)) goto out_screen; /* do first update instantly */ next_update = time(NULL); conf_dec_count(); /* dispatcher */ while (!g_exit) { /* if we are in error state, try to retrieve a connection first */ if (mpd.error) { if (retry_count-- <= 0) { /* each minute */ if (mpd_start_connection(&mpd)) { mpd.error = false; } else { retry_count = RETRY_INTERVAL; } } if (mpd.error) { g_usleep(1000000); continue; } } current = time(NULL); g_usleep(1000000); mpd_status_queue_update(mpd.mpd); mpd_status_check(mpd.mpd); mpd_update_status_time(&mpd); /* check playlists ? */ if (current > next_update) { mpd_update_playlist_menu(&mpd); next_update = time(NULL) + 60; } if (current > mpd.stop_time) { mpd_player_stop(mpd.mpd); mpd.stop_time = UINT_MAX; service_thread_command(mpd.lcd->service_thread, "menu_set_item \"\" mpd_standby -value 0\n"); } } out_screen: mpd_deinit(&mpd); out: if (mpd.mpd) mpd_free(mpd.mpd); if (mpd.current_list) mpd_free_playlist(mpd.current_list); service_thread_unregister_client(mpd.lcd->service_thread, MODULE_NAME); mpd_song_delete(mpd.current_song); connection_delete(mpd.connection); return NULL; }
/* process_packet: * Callback which processes a packet captured by libpcap. */ void process_packet(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt) { struct tcphdr tcp; int off, len, delta; connection *C, c; struct sockaddr_storage src, dst; struct sockaddr *s, *d; uint8_t proto; s = (struct sockaddr *)&src; d = (struct sockaddr *)&dst; if (handle_link_layer(&datalink_info, pkt, hdr->caplen, &proto, &off)) return; if (layer3_find_tcp(pkt, proto, &off, s, d, &tcp)) return; len = hdr->caplen - off; /* XXX fragmented packets and other nasties. */ /* try to find the connection slot associated with this. */ C = find_connection(s, d); /* no connection at all, so we need to allocate one. */ if (!C) { log_msg(LOG_INFO, "new connection: %s", connection_string(s,d)); C = alloc_connection(); *C = connection_new(s, d); /* This might or might not be an entirely new connection (SYN flag * set). Either way we need a sequence number to start at. */ (*C)->isn = ntohl(tcp.th_seq); } /* Now we need to process this segment. */ c = *C; delta = 0;/*tcp.syn ? 1 : 0;*/ /* NB (STD0007): * SEG.LEN = the number of octets occupied by the data in the * segment (counting SYN and FIN) */ #if 0 if (tcp.syn) /* getting a new isn. */ c->isn = htonl(tcp.seq); #endif if (tcp.th_flags & TH_RST) { /* Looks like this connection is bogus, and so might be a * connection going the other way. */ log_msg(LOG_INFO, "connection reset: %s", connection_string(s, d)); connection_delete(c); *C = NULL; if ((C = find_connection(d, s))) { connection_delete(*C); *C = NULL; } return; } if (len > 0) { /* We have some data in the packet. If this data occurred after * the first data we collected for this connection, then save it * so that we can look for images. Otherwise, discard it. */ unsigned int offset; offset = ntohl(tcp.th_seq); /* Modulo 2**32 arithmetic; offset = seq - isn + delta. */ if (offset < (c->isn + delta)) offset = 0xffffffff - (c->isn + delta - offset); else offset -= c->isn + delta; if (offset > c->len + WRAPLEN) { /* Out-of-order packet. */ log_msg(LOG_INFO, "out of order packet: %s", connection_string(s, d)); } else { connection_push(c, pkt + off, offset, len); extract_media(c); } } if (tcp.th_flags & TH_FIN) { /* Connection closing; mark it as closed, but let sweep_connections * free it if appropriate. */ log_msg(LOG_INFO, "connection closing: %s, %d bytes transferred", connection_string(s, d), c->len); c->fin = 1; } /* sweep out old connections */ sweep_connections(); }