removed TTY port constraints, added client activity timestamps

This commit is contained in:
Igor Socec 2014-03-19 16:16:21 +01:00
parent 5a303705e6
commit 1001f3ad9c
6 changed files with 66 additions and 29 deletions

View file

@ -6,12 +6,14 @@
/* Closes client connection. */ /* Closes client connection. */
int client_close(struct client_t *client) { int client_close(struct client_t *client) {
char timestamp[TIMESTAMP_LEN];
/* force closing in case of error */ /* force closing in case of error */
if (close(client->socket) == -1) { if (close(client->socket) == -1) {
close(client->socket); close(client->socket);
} }
client->socket = -1; client->socket = -1;
fprintf(stderr,"[%s] socket closed for client %s\n", __func__, client->ip_string); time2string(time(NULL), timestamp);
fprintf(stderr,"[%s] socket closed for client %s @ %s\n", __func__, client->ip_string, timestamp);
return 0; return 0;
} }
@ -46,6 +48,9 @@ int client_read(struct client_t *client) {
/* handle special telnet characters coming from client */ /* handle special telnet characters coming from client */
telnet_handle_client_read(client->data, &len); telnet_handle_client_read(client->data, &len);
/* grab current time and store it as client last activity */
client->last_active = time(NULL);
return len; return len;
} }

View file

@ -11,14 +11,12 @@
#define NAME "moxerver" #define NAME "moxerver"
#define SERVER_WAIT_TIMEOUT 5 /* seconds for select() timeout in server loop */ #define SERVER_WAIT_TIMEOUT 5 /* seconds for select() timeout in server loop */
#define PORT_MIN 4001 /* minimum TCP port number */
#define PORT_MAX 4008 /* maximum TCP port number */
/* Prints help message. */ /* Prints help message. */
static void usage() { static void usage() {
//TODO maybe some styling should be done //TODO maybe some styling should be done
fprintf(stderr, "Usage: moxerver -p tcp_port -t tty_path [-h]\n"); fprintf(stderr, "Usage: %s -p tcp_port -t tty_path [-h]\n", NAME);
fprintf(stderr, "- tcp_port range [%d .. %d]\n\n", PORT_MIN, PORT_MAX); fprintf(stderr, "\n");
} }
/* Performs cleanup and exit. */ /* Performs cleanup and exit. */
@ -42,6 +40,12 @@ void quit_handler(int signum) {
cleanup(0); cleanup(0);
} }
/* Converts from time in seconds from Epoch to conveniently formatted string. */
int time2string(time_t time, char* timestamp) {
strftime(timestamp, TIMESTAMP_LEN, TIMESTAMP_FORMAT, localtime(&time));
return 0;
}
/* MoxaNix main program loop. */ /* MoxaNix main program loop. */
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -94,14 +98,6 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
} }
/* check arguments */
if (tcp_port < PORT_MIN || tcp_port > PORT_MAX) {
//TODO do we really put port constraints in moxerver? Maybe higher SW layer that controls all servers should handle it.
fprintf(stderr, "[%s] error: port number out of %d-%d range\n\n",
NAME, PORT_MIN, PORT_MAX);
usage();
return -1;
}
/* introduction message */ /* introduction message */
fprintf(stderr, "[%s] === MoxaNix ===\n", NAME); fprintf(stderr, "[%s] === MoxaNix ===\n", NAME);
@ -152,6 +148,7 @@ int main(int argc, char *argv[]) {
ret = server_accept(&server, &client); ret = server_accept(&server, &client);
if ( ret != 0) { if ( ret != 0) {
/* print error but continue waiting for connection request */ /* print error but continue waiting for connection request */
//TODO maybe we should break here to avoid endless loop
fprintf(stderr, "[%s] problem accepting client\n", NAME); fprintf(stderr, "[%s] problem accepting client\n", NAME);
continue; continue;
} }
@ -184,7 +181,17 @@ int main(int argc, char *argv[]) {
} }
} }
if (ret == 0) { if (ret == 0) {
fprintf(stderr, "[%s] server waiting\n", NAME); /* do something with inactive client */
if (client.socket != -1) {
//TODO we could drop client if inactive for some time
time_t current_time = time(NULL);
fprintf(stderr, "[%s] client last active %u seconds ago\n", NAME,
(unsigned int) (current_time - client.last_active));
}
/* do something while listening for client connections */
else {
fprintf(stderr, "[%s] listening for client connection\n", NAME);
}
} }
} /* END while() loop */ } /* END while() loop */

View file

@ -10,10 +10,12 @@
#include <netinet/tcp.h> /* TCP_NODELAY */ #include <netinet/tcp.h> /* TCP_NODELAY */
#include <arpa/inet.h> #include <arpa/inet.h>
#include <termios.h> #include <termios.h>
#include <time.h>
#define DATA_BUFLEN 128 #define DATABUF_LEN 128
#define DEV_PATH 32 #define DEV_PATH 32
#define TIMESTAMP_FORMAT "%d.%m.%Y. %H:%M:%S"
#define TIMESTAMP_LEN 20+1 /* calculated following timestamp format */
/* Structures used for communication parameters. */ /* Structures used for communication parameters. */
struct server_t { struct server_t {
@ -26,14 +28,15 @@ struct client_t {
int socket; /* client socket */ int socket; /* client socket */
struct sockaddr_in address; /* client address information */ struct sockaddr_in address; /* client address information */
char ip_string[INET_ADDRSTRLEN]; /* client IP address as a string */ char ip_string[INET_ADDRSTRLEN]; /* client IP address as a string */
char data[DATA_BUFLEN]; /* buffer for data received from client */ time_t last_active; /* time of client's last activity in seconds from Epoch */
char data[DATABUF_LEN]; /* buffer for data received from client */
}; };
struct tty_t { struct tty_t {
int fd; /* tty file descriptor */ int fd; /* tty file descriptor */
struct termios ttyset; /* tty termios settings */ struct termios ttyset; /* tty termios settings */
char path[DEV_PATH]; /* tty device path */ char path[DEV_PATH]; /* tty device path */
char data[DATA_BUFLEN]; /* buffer for data received from tty */ char data[DATABUF_LEN]; /* buffer for data received from tty */
}; };
@ -43,6 +46,17 @@ struct client_t client; /* connected client structure */ //TODO working with on
struct tty_t tty_dev; /* connected tty device */ struct tty_t tty_dev; /* connected tty device */
/* Global functions used throughout the application. */
/**
* Converts from time in seconds from Epoch to conveniently formatted string.
*
* Returns:
* 0 always
*/
int time2string(time_t time, char* timestamp);
/* Functions handling server operation. */ /* Functions handling server operation. */
/** /**
@ -58,7 +72,7 @@ int server_setup(struct server_t *server, unsigned int port);
* Closes the server socket. * Closes the server socket.
* *
* Returns: * Returns:
* 0 always, but internally tries closing again if it fails. * 0 always, but internally tries closing again if it fails
*/ */
int server_close(struct server_t *server); int server_close(struct server_t *server);
@ -86,12 +100,13 @@ int server_reject(struct server_t *server);
* Closes client connection. * Closes client connection.
* *
* Returns: * Returns:
* 0 always, but internally tries closing again if it fails. * 0 always, but internally tries closing again if it fails
*/ */
int client_close(struct client_t *client); int client_close(struct client_t *client);
/** /**
* Reads data from client into client data buffer. * Reads data from client into client data buffer.
* Also updates client's last activity timestamp.
* *
* Returns: * Returns:
* - number of read bytes on success, * - number of read bytes on success,

View file

@ -8,6 +8,7 @@
int server_setup(struct server_t *server, unsigned int port) { int server_setup(struct server_t *server, unsigned int port) {
int opt; int opt;
char timestamp[TIMESTAMP_LEN];
/* set up server address information */ /* set up server address information */
server->address.sin_family = AF_INET; /* use IPv4 address family */ server->address.sin_family = AF_INET; /* use IPv4 address family */
@ -52,17 +53,20 @@ int server_setup(struct server_t *server, unsigned int port) {
return -errno; return -errno;
} }
fprintf(stderr,"[%s] server is up, listening for client connection\n", __func__); time2string(time(NULL), timestamp);
fprintf(stderr,"[%s] server is up @ %s\n", __func__, timestamp);
return 0; return 0;
} }
/* Closes the server socket. */ /* Closes the server socket. */
int server_close(struct server_t *server) { int server_close(struct server_t *server) {
char timestamp[TIMESTAMP_LEN];
/* force closing in case of error */ /* force closing in case of error */
if (close(server->socket) == -1) { if (close(server->socket) == -1) {
close(server->socket); close(server->socket);
} }
fprintf(stderr,"[%s] socket closed, server is down\n", __func__); time2string(time(NULL), timestamp);
fprintf(stderr,"[%s] socket closed, server is down @ %s\n", __func__, timestamp);
return 0; return 0;
} }
@ -70,6 +74,7 @@ int server_close(struct server_t *server) {
int server_accept(struct server_t *server, struct client_t *accepted_client) { int server_accept(struct server_t *server, struct client_t *accepted_client) {
int namelen; int namelen;
char timestamp[TIMESTAMP_LEN];
/* accept connection request */ /* accept connection request */
namelen = sizeof(accepted_client->address); namelen = sizeof(accepted_client->address);
@ -88,10 +93,13 @@ int server_accept(struct server_t *server, struct client_t *accepted_client) {
inet_ntop(accepted_client->address.sin_family, &accepted_client->address.sin_addr.s_addr, inet_ntop(accepted_client->address.sin_family, &accepted_client->address.sin_addr.s_addr,
accepted_client->ip_string, INET_ADDRSTRLEN); accepted_client->ip_string, INET_ADDRSTRLEN);
/* grab current time and store it as client last activity*/
accepted_client->last_active = time(NULL);
/* print client information */ /* print client information */
//TODO also print timestamp time2string(accepted_client->last_active, timestamp);
fprintf(stderr, "[%s] accepted client %s on port %u\n", __func__, fprintf(stderr, "[%s] accepted client %s on port %u @ %s\n", __func__,
accepted_client->ip_string, server->port); accepted_client->ip_string, server->port, timestamp);
return 0; return 0;
} }
@ -101,6 +109,7 @@ int server_reject(struct server_t *server) {
int namelen; int namelen;
struct client_t rclient; struct client_t rclient;
char reject_msg[128]; char reject_msg[128];
char timestamp[TIMESTAMP_LEN];
/* accept connection request */ /* accept connection request */
namelen = sizeof(rclient.address); namelen = sizeof(rclient.address);
@ -111,6 +120,7 @@ int server_reject(struct server_t *server) {
/* close connection */ /* close connection */
close(rclient.socket); close(rclient.socket);
fprintf(stderr, "[%s] rejected new client request, there is alredy a client connected\n", __func__); time2string(time(NULL), timestamp);
fprintf(stderr, "[%s] rejected new client request @ %s\n", __func__, timestamp);
return 0; return 0;
} }

View file

@ -96,7 +96,7 @@ int telnet_set_character_mode(struct client_t *client) {
int telnet_handle_client_read(char *databuf, int *datalen) { int telnet_handle_client_read(char *databuf, int *datalen) {
int i; int i;
char newdata[DATA_BUFLEN]; char newdata[DATABUF_LEN];
int newlen = 0; int newlen = 0;
/* process data using a new buffer */ /* process data using a new buffer */
@ -123,7 +123,7 @@ int telnet_handle_client_read(char *databuf, int *datalen) {
int telnet_handle_client_write(char *databuf, int *datalen) { int telnet_handle_client_write(char *databuf, int *datalen) {
int i; int i;
char newdata[DATA_BUFLEN]; char newdata[DATABUF_LEN];
int newlen = 0; int newlen = 0;
/* process data using a new buffer */ /* process data using a new buffer */

2
tty.c
View file

@ -93,7 +93,7 @@ void *tty_thread_func(void *arg) {
ret = select(tty_dev->fd + 1, &read_fds, NULL, NULL, &tv); ret = select(tty_dev->fd + 1, &read_fds, NULL, NULL, &tv);
if (ret > 0 && FD_ISSET(tty_dev->fd, &read_fds)) { if (ret > 0 && FD_ISSET(tty_dev->fd, &read_fds)) {
br = read(tty_dev->fd, tty_dev->data, DATA_BUFLEN); br = read(tty_dev->fd, tty_dev->data, DATABUF_LEN);
client_write(&client, tty_dev->data, br); client_write(&client, tty_dev->data, br);
} }
else { else {