Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standby support #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ Usage takes up to 3 command line options:
* `-p port` Server port to connect to
* `-l port` Listening port for clients to connect to, HTTP status port will be
equal to this plus one
* `-d` Connect to server only when first client arrives and exit when last disconnects
* `-r` Close connection with the server and restart it when last client disconnects

Note: For standby use (for example, when running as a daemon), use both flags `-d -r`.
When running in this way the RTL_TCP is only active (reading samples) when some client is connected.
In any order case, the RTL_TCP and RTLMUX processes are in standby (idle).
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a spelling mistake on 'order', which should be 'other'.

43 changes: 42 additions & 1 deletion cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ const char *gengetopt_args_info_help[] = {
" -p, --port=port rtl_tcp port (default=`1234')",
" -h, --host=address rtl_tcp host address (default=`localhost')",
" -l, --listen=port Listening port for client connections (default=`7878')",
" -d, --delayed Delayed \n connection to the server (default=off)",
" -r, --restart Restart server's connection when last \n client disconnects (default=off)",
0
};

typedef enum {ARG_NO
, ARG_FLAG
, ARG_STRING
, ARG_INT
} cmdline_c_arg_type;
Expand Down Expand Up @@ -92,6 +95,8 @@ void clear_given (struct gengetopt_args_info *args_info)
args_info->port_given = 0 ;
args_info->host_given = 0 ;
args_info->listen_given = 0 ;
args_info->delayed_given = 0 ;
args_info->restart_given = 0 ;
}

static
Expand All @@ -104,6 +109,8 @@ void clear_args (struct gengetopt_args_info *args_info)
args_info->host_orig = NULL;
args_info->listen_arg = 7878;
args_info->listen_orig = NULL;
args_info->delayed_flag = 0;
args_info->restart_flag = 0;

}

Expand All @@ -117,6 +124,8 @@ void init_args_info(struct gengetopt_args_info *args_info)
args_info->port_help = gengetopt_args_info_help[2] ;
args_info->host_help = gengetopt_args_info_help[3] ;
args_info->listen_help = gengetopt_args_info_help[4] ;
args_info->delayed_help = gengetopt_args_info_help[5] ;
args_info->restart_help = gengetopt_args_info_help[6] ;

}

Expand Down Expand Up @@ -244,6 +253,10 @@ cmdline_c_dump(FILE *outfile, struct gengetopt_args_info *args_info)
write_into_file(outfile, "host", args_info->host_orig, 0);
if (args_info->listen_given)
write_into_file(outfile, "listen", args_info->listen_orig, 0);
if (args_info->delayed_given)
write_into_file(outfile, "delayed", 0, 0 );
if (args_info->restart_given)
write_into_file(outfile, "restart", 0, 0 );


i = EXIT_SUCCESS;
Expand Down Expand Up @@ -410,6 +423,9 @@ int update_arg(void *field, char **orig_field,
val = possible_values[found];

switch(arg_type) {
case ARG_FLAG:
*((int *)field) = !*((int *)field);
break;
case ARG_INT:
if (val) *((int *)field) = strtol (val, &stop_char, 0);
break;
Expand Down Expand Up @@ -440,6 +456,7 @@ int update_arg(void *field, char **orig_field,
/* store the original value */
switch(arg_type) {
case ARG_NO:
case ARG_FLAG:
break;
default:
if (value && orig_field) {
Expand Down Expand Up @@ -499,10 +516,12 @@ cmdline_c_internal (
{ "port", 1, NULL, 'p' },
{ "host", 1, NULL, 'h' },
{ "listen", 1, NULL, 'l' },
{ "delayed", 0, NULL, 'd' },
{ "restart", 0, NULL, 'r' },
{ 0, 0, 0, 0 }
};

c = getopt_long (argc, argv, "Vp:h:l:", long_options, &option_index);
c = getopt_long (argc, argv, "Vp:h:l:dr", long_options, &option_index);

if (c == -1) break; /* Exit from `while (1)' loop. */

Expand Down Expand Up @@ -549,6 +568,28 @@ cmdline_c_internal (
goto failure;

break;
case 'd': /* Delayed
connection to the server. */


if (update_arg((void *)&(args_info->delayed_flag), 0, &(args_info->delayed_given),
&(local_args_info.delayed_given), optarg, 0, 0, ARG_FLAG,
check_ambiguity, override, 1, 0, "delayed", 'd',
additional_error))
goto failure;

break;
case 'r': /* Restart server's connection when last
client disconnects. */


if (update_arg((void *)&(args_info->restart_flag), 0, &(args_info->restart_given),
&(local_args_info.restart_given), optarg, 0, 0, ARG_FLAG,
check_ambiguity, override, 1, 0, "restart", 'r',
additional_error))
goto failure;

break;

case 0: /* Long option with no short option */
if (strcmp (long_options[option_index].name, "help") == 0) {
Expand Down
10 changes: 10 additions & 0 deletions cmdline.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,22 @@ struct gengetopt_args_info
int listen_arg; /**< @brief Listening port for client connections (default='7878'). */
char * listen_orig; /**< @brief Listening port for client connections original value given at command line. */
const char *listen_help; /**< @brief Listening port for client connections help description. */
int delayed_flag; /**< @brief Delayed
connection to the server (default=off). */
const char *delayed_help; /**< @brief Delayed
connection to the server help description. */
int restart_flag; /**< @brief Restart server's connection when last
client disconnects (default=off). */
const char *restart_help; /**< @brief Restart server's connection when last
client disconnects help description. */

unsigned int help_given ; /**< @brief Whether help was given. */
unsigned int version_given ; /**< @brief Whether version was given. */
unsigned int port_given ; /**< @brief Whether port was given. */
unsigned int host_given ; /**< @brief Whether host was given. */
unsigned int listen_given ; /**< @brief Whether listen was given. */
unsigned int delayed_given ; /**< @brief Whether delayed was given. */
unsigned int restart_given ; /**< @brief Whether restart was given. */

} ;

Expand Down
4 changes: 3 additions & 1 deletion config.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ int convertConfig(struct gengetopt_args_info *args) {
config.host = args->host_arg;
config.port = args->port_arg;
config.clientPort = args->listen_arg;

config.delayed = args->delayed_flag;
config.restart = args->restart_flag;

return 1;
}

Expand Down
2 changes: 2 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ struct config {
char *host;
uint16_t port;
uint16_t clientPort;
int delayed;
int restart;
};

extern struct config config;
Expand Down
10 changes: 8 additions & 2 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ int main(int argc, char **argv) {
sigact.sa_flags = 0;
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGINT, &sigact, NULL);
restart:
pthread_create(&threadServer, NULL, serverThread, NULL);

pthread_join(threadServer, NULL);

if (timeToExit == 2) {
slog(LOG_INFO, SLOG_INFO, "Restarting.");
timeToExit = 0;
goto restart;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it could be better handled in just a normal loop, like:

do {
  pthread_create();
  ..
  pthread_join();
  if (timeToExit == 2) {
    slog restarting;
    timeToExit = 0;
  }
} while (timeToExit != 1);

}
}
6 changes: 5 additions & 1 deletion options.ggo
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ option "port" p "rtl_tcp port"
option "host" h "rtl_tcp host address"
string typestr="address" default="localhost" optional
option "listen" l "Listening port for client connections"
int typestr="port" default="7878" optional
int typestr="port" default="7878" optional option "delayed" d "Delayed
connection to the server"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line wrapping (and the next one) causes some issues in formatting for the --help and comments in the cmdline handler.

flag off option "restart" r "Restart server's connection when last
client disconnects"
flag off
34 changes: 27 additions & 7 deletions rtlmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,10 @@ static void serverReadCB(struct bufferevent *bev, void *ctx) {
slog(LOG_INFO, SLOG_INFO, "Connected to server.");
} else { // Failed to receive the magic header
slog(LOG_ERROR, SLOG_ERROR, "Failed to receive magic header from server.");
bufferevent_free(bev);
connectToServerSoon(ctx);
return;
//bufferevent_free(bev);
//connectToServerSoon(ctx);
//return;
serverInfo.state = SERVER_CONNECTED;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really see why this is being set to SERVER_CONNECTED when it hasn't actually happened. This would then go on using the buffer and context on a bad connection. It seems you'd likely just want to use the timeToExit = 2 here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More or less... yes!

}
// Send stored and set parameters on reconnect
int i;
Expand Down Expand Up @@ -251,6 +252,10 @@ static void serverReadCB(struct bufferevent *bev, void *ctx) {
if(sendDataToAllClients(data) == 0) {
// No one was listening
free(data);
if (config.delayed) {
slog(LOG_INFO, SLOG_INFO, "Last user disconnected.");
if (config.restart) timeToExit = 2; else timeToExit = 1;
}
} else {
dataBlocks++;
dataBlocksSize += data->len;
Expand Down Expand Up @@ -388,6 +393,11 @@ static void connectCB(struct evconnlistener *listener,
base, sock, BEV_OPT_CLOSE_ON_FREE);
#endif

if (config.delayed && (serverConnection == NULL || LIST_FIRST(&clients) == NULL)) {
slog(LOG_INFO, SLOG_INFO, "Connection to server triggered.");
connectToServer(&serverConnection);
}

struct client *client = addClient(bev, ptr);
memcpy(&client->sa, addr, len);
char ipBuf[128];
Expand All @@ -397,7 +407,7 @@ static void connectCB(struct evconnlistener *listener,
evutil_inet_ntop(client->sa.sa_family, &client->sin6.sin6_addr, ipBuf, 128);
else
snprintf(ipBuf, 128, "from unknown address");
slog(LOG_INFO, SLOG_INFO, "Connection from client %s", ipBuf);
slog(LOG_INFO, SLOG_INFO, "Connection from client %s%s", ipBuf, LIST_NEXT(client,peer) == NULL ? " (first!)" : "");
bufferevent_setcb(bev, clientReadCB, NULL, errorEventCB, client);
bufferevent_setwatermark(bev, EV_WRITE, 0, 4*1024*1024); // Limit output to 4MB?
bufferevent_enable(bev, EV_READ|EV_WRITE);
Expand Down Expand Up @@ -483,8 +493,12 @@ void *serverThread(void *arg) {
}

slog(LOG_INFO, SLOG_INFO, "Listening for clients on port %d", config.clientPort);

connectToServer(&serverConnection);

if (!config.delayed) {
connectToServer(&serverConnection);
} else {
slog(LOG_INFO, SLOG_INFO, "connection to server delayed.");
}

struct evhttp *http;
struct evhttp_bound_socket *handle;
Expand Down Expand Up @@ -539,6 +553,12 @@ void *serverThread(void *arg) {
evhttp_free(http);

event_base_free(event_base);

if (serverConnection != NULL) {
bufferevent_free(serverConnection);
serverInfo.state = SERVER_DISCONNECTED;
slog(LOG_INFO, SLOG_INFO, "Disconnecting from server.");
}

slog(LOG_INFO, SLOG_INFO, "End of server thread.");
return NULL;
}