/** the file containing user information (public key, permissions) */
char *user_list_file = NULL;
-extern void dccp_send_init(struct sender *);
-extern void http_send_init(struct sender *);
-extern void ortp_send_init(struct sender *);
-
-/** the list of supported senders */
-struct sender senders[] = {
- {
- .name = "http",
- .init = http_send_init,
- },
- {
- .name = "dccp",
- .init = dccp_send_init,
- },
-#ifdef HAVE_ORTP
- {
- .name = "ortp",
- .init = ortp_send_init,
- },
-#endif
- {
- .name = NULL,
- }
-};
-
-
/* global variables for server-internal use */
static FILE *logfile;
static int mmd_mutex, mmd_shm_id;
static int signal_pipe;
+struct server_command_task {
+ /** TCP port on which para_server listens for connections. */
+ int listen_fd;
+ /** Copied from para_server's main function. */
+ int argc;
+ /** Argument vector passed to para_server's main function. */
+ char **argv;
+ /** The command task structure for scheduling. */
+ //struct task task;
+ char dummy;
+};
+
/**
* para_server's log function
*
mmd->active_connections = 0;
mmd->vss_status_flags = VSS_NEXT;
mmd->new_vss_status_flags = VSS_NEXT;
- mmd->sender_cmd_data.cmd_num = -1;
return;
err_out:
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
exit(EXIT_FAILURE);
}
-static unsigned init_network(void)
+static void init_command_task(struct server_command_task *sct)
{
- int fd, ret = para_listen(AF_UNSPEC, IPPROTO_TCP, conf.port_arg);
+ int ret;
+ PARA_NOTICE_LOG("initializing tcp command socket\n");
+ ret = para_listen(AF_UNSPEC, IPPROTO_TCP, conf.port_arg);
if (ret < 0)
goto err;
- fd = ret;
- ret = mark_fd_nonblocking(fd);
+ sct->listen_fd = ret;
+ ret = mark_fd_nonblocking(sct->listen_fd);
if (ret < 0)
goto err;
- add_close_on_fork_list(fd); /* child doesn't need the listener */
- return fd;
+ add_close_on_fork_list(sct->listen_fd); /* child doesn't need the listener */
+ return;
err:
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
exit(EXIT_FAILURE);
(unsigned) afs_socket_cookie);
}
-static unsigned server_init(int argc, char **argv)
+static void server_init(int argc, char **argv)
{
/* connector's address information */
- int sockfd;
struct server_cmdline_parser_params params = {
.override = 0,
.initialize = 1,
daemon_init();
PARA_NOTICE_LOG("initializing audio format handlers\n");
afh_init();
- PARA_NOTICE_LOG("initializing virtual streaming system\n");
mmd->server_pid = getpid();
setup_signal_handling();
PARA_NOTICE_LOG("initializing the audio file selector\n");
init_afs();
+ PARA_NOTICE_LOG("initializing virtual streaming system\n");
vss_init();
mmd_lock();
- /* init network socket */
- PARA_NOTICE_LOG("initializing tcp command socket\n");
- sockfd = init_network();
PARA_NOTICE_LOG("server init complete\n");
- return sockfd;
}
/*
}
}
+static int server_select(int max_fileno, fd_set *readfds, fd_set *writefds,
+ struct timeval *timeout_tv)
+{
+ int ret;
+
+ status_refresh();
+ mmd_unlock();
+ ret = para_select(max_fileno + 1, readfds, writefds, timeout_tv);
+ mmd_lock();
+ return ret;
+}
+
+static void command_pre_select(int *max_fileno, fd_set *rfds, char *dummy_ptr)
+{
+ struct server_command_task *sct = container_of(dummy_ptr, struct server_command_task, dummy);
+ para_fd_set(sct->listen_fd, rfds, max_fileno);
+}
+
+static void command_post_select(fd_set *rfds, char *dummy_ptr)
+{
+ struct server_command_task *sct = container_of(dummy_ptr, struct server_command_task, dummy);
+
+ int new_fd, ret;
+ char *peer_name;
+ pid_t child_pid;
+
+ if (!FD_ISSET(sct->listen_fd, rfds))
+ return;
+ ret = para_accept(sct->listen_fd, NULL, 0);
+ if (ret < 0)
+ goto out;
+ new_fd = ret;
+ peer_name = remote_name(new_fd);
+ PARA_INFO_LOG("got connection from %s, forking\n", peer_name);
+ mmd->num_connects++;
+ mmd->active_connections++;
+ random();
+ child_pid = fork();
+ if (child_pid < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
+ goto out;
+ }
+ if (child_pid) {
+ close(new_fd);
+ /* parent keeps accepting connections */
+ return;
+ }
+ alarm(ALARM_TIMEOUT);
+ close_listed_fds();
+ para_signal_shutdown();
+ /*
+ * put info on who we are serving into argv[0] to make
+ * client ip visible in top/ps
+ */
+// for (i = argc - 1; i >= 0; i--)
+// memset(argv[i], 0, strlen(argv[i]));
+// sprintf(argv[0], "para_server (serving %s)", peer_name);
+ return handle_connect(new_fd, peer_name);
+out:
+ if (ret < 0)
+ PARA_CRIT_LOG("%s\n", para_strerror(-ret));
+}
+
/**
* the main function of para_server
*
*/
int main(int argc, char *argv[])
{
- /* listen on sock_fd, new connection on new_fd */
- int sockfd, new_fd;
- char *peer_name;
- int i, max_fileno, ret;
- pid_t chld_pid;
+ int max_fileno, ret;
fd_set rfds, wfds;
struct timeval *timeout;
+ struct server_command_task server_command_task_struct;
+
valid_fd_012();
- sockfd = server_init(argc, argv);
+ server_init(argc, argv);
+ init_command_task(&server_command_task_struct);
repeat:
FD_ZERO(&rfds);
FD_ZERO(&wfds);
max_fileno = -1;
- /* check socket and signal pipe in any case */
- para_fd_set(sockfd, &rfds, &max_fileno);
+ command_pre_select(&max_fileno, &rfds, &server_command_task_struct.dummy);
para_fd_set(signal_pipe, &rfds, &max_fileno);
timeout = vss_preselect(&rfds, &wfds, &max_fileno);
- status_refresh();
- mmd_unlock();
- ret = para_select(max_fileno + 1, &rfds, &wfds, timeout);
- mmd_lock();
- if (ret < 0)
- goto repeat;
+ server_select(max_fileno + 1, &rfds, &wfds, timeout);
vss_post_select(&rfds, &wfds);
- status_refresh();
if (FD_ISSET(signal_pipe, &rfds)) {
int sig;
pid_t pid;
exit(EXIT_FAILURE);
}
}
- if (!FD_ISSET(sockfd, &rfds))
- goto repeat;
-
- new_fd = para_accept(sockfd, NULL, 0);
- if (new_fd < 0)
- goto repeat;
- peer_name = remote_name(new_fd);
- PARA_INFO_LOG("got connection from %s, forking\n", peer_name);
- mmd->num_connects++;
- mmd->active_connections++;
- random();
- chld_pid = fork();
- if (chld_pid < 0) {
- PARA_CRIT_LOG("fork failed\n");
- goto repeat;
- }
- if (chld_pid) {
- close(new_fd);
- /* parent keeps accepting connections */
- goto repeat;
- }
- alarm(ALARM_TIMEOUT);
- close_listed_fds();
- para_signal_shutdown();
- /*
- * put info on who we are serving into argv[0] to make
- * client ip visible in top/ps
- */
- for (i = argc - 1; i >= 0; i--)
- memset(argv[i], 0, strlen(argv[i]));
- sprintf(argv[0], "para_server (serving %s)", peer_name);
- return handle_connect(new_fd, peer_name);
+ command_post_select(&rfds, &server_command_task_struct.dummy);
+ goto repeat;
}