removed TTY port constraints, added client activity timestamps
This commit is contained in:
parent
5a303705e6
commit
1001f3ad9c
6 changed files with 66 additions and 29 deletions
7
client.c
7
client.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
moxerver.c
33
moxerver.c
|
@ -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 */
|
||||||
|
|
27
moxerver.h
27
moxerver.h
|
@ -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,
|
||||||
|
|
22
server.c
22
server.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
4
telnet.c
4
telnet.c
|
@ -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
2
tty.c
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue