37 #include <ldns/ldns.h> 42 #include <sys/select.h> 43 #include <sys/socket.h> 46 #ifdef HAVE_SYS_TYPES_H 47 # include <sys/types.h> 52 #include <sys/types.h> 55 #include "clientpipe.h" 102 #define SE_CMDH_CMDLEN 7 103 #define MAX_CLIENT_CONN 8 105 static char const * module_str =
"cmdhandler";
110 cmd_funcs_avail(
void)
167 while (fb[cmd_iter]) {
168 if (!fb[cmd_iter]()->
handles(
"time leap", 10))
169 (*fb[cmd_iter])()->usage(sockfd);
179 while (fb[cmd_iter]) {
180 if (fb[cmd_iter]()->
handles(cmd, n))
181 return fb[cmd_iter]();
200 time_t tstart = time(NULL);
206 if (n == 0)
return 0;
214 client_printf_err(sockfd,
"Error parsing arguments\n",
215 fb->
cmdname, time(NULL) - tstart);
216 client_printf(sockfd,
"Usage:\n\n");
218 }
else if (ret == 0) {
219 client_printf_err(sockfd,
"%s completed in %ld seconds.\n",
220 fb->
cmdname, time(NULL) - tstart);
222 ods_log_debug(
"[%s] done handling command %s[%ld]", module_str, cmd, (
long)n);
226 client_printf_err(sockfd,
"Unknown command %s.\n", cmd?cmd:
"(null)");
227 client_printf(sockfd,
"Commands:\n");
251 extract_msg(
char* buf,
int *pos,
int buflen,
int *exitcode,
254 char data[ODS_SE_MAXLINE+1], opc;
260 assert(*pos <= buflen);
261 assert(ODS_SE_MAXLINE >= buflen);
264 if (*pos < 3)
return 0;
266 datalen = (buf[1]<<8) | (buf[2]&0xFF);
267 if (datalen+3 <= *pos) {
269 memset(data, 0, ODS_SE_MAXLINE+1);
270 memcpy(data, buf+3, datalen);
272 memmove(buf, buf+datalen+3, *pos);
273 ods_str_trim(data, 0);
275 if (opc == CLIENT_OPC_STDIN) {
276 *exitcode = cmdhandler_perform_command(cmdc, data, strlen(data));
279 }
else if (datalen+3 > buflen) {
281 ods_log_error(
"[%s] Message received to big, truncating.", module_str);
283 buf[1] = datalen >> 8;
284 buf[2] = datalen & 0xFF;
302 char buf[ODS_SE_MAXLINE+4];
309 int n = read(cmdc->
client_fd, buf+bufpos, ODS_SE_MAXLINE-bufpos+3);
313 if (errno == EAGAIN || errno == EWOULDBLOCK)
continue;
317 r = extract_msg(buf, &bufpos, ODS_SE_MAXLINE, &exitcode, cmdc);
319 ods_log_error(
"[%s] Error receiving message from client.", module_str);
322 if (!client_exit(cmdc->
client_fd, exitcode)) {
323 ods_log_error(
"[%s] Error sending message to client.", module_str);
334 cmdhandler_accept_client(
void* arg)
341 if((err=pthread_sigmask(SIG_SETMASK, &sigset, NULL)))
342 ods_fatal_exit(
"[%s] pthread_sigmask: %s", module_str, strerror(err));
348 client_printf_err(cmdc->
client_fd,
"Failed to open DB connection.\n");
353 cmdhandler_handle_client_conversation(cmdc);
370 struct sockaddr_un servaddr;
376 ods_log_error(
"[%s] unable to create: no socket filename", module_str);
379 ods_log_assert(filename);
380 ods_log_debug(
"[%s] create socket %s", module_str, filename);
383 listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
385 ods_log_error(
"[%s] unable to create, socket() failed: %s", module_str,
390 flags = fcntl(listenfd, F_GETFL, 0);
392 ods_log_error(
"[%s] unable to create, fcntl(F_GETFL) failed: %s",
393 module_str, strerror(errno));
398 if (fcntl(listenfd, F_SETFL, flags) < 0) {
399 ods_log_error(
"[%s] unable to create, fcntl(F_SETFL) failed: %s",
400 module_str, strerror(errno));
406 bzero(&servaddr,
sizeof(servaddr));
407 servaddr.sun_family = AF_UNIX;
408 strncpy(servaddr.sun_path, filename,
sizeof(servaddr.sun_path) - 1);
410 unlink(servaddr.sun_path);
414 ret = bind(listenfd, (
const struct sockaddr*) &servaddr,
sizeof(
struct sockaddr_un));
416 ods_log_error(
"[%s] unable to create, bind() failed: %s", module_str,
423 ods_log_error(
"[%s] unable to create, listen() failed: %s", module_str,
459 struct sockaddr_un cliaddr;
463 int flags, connfd = 0, ret = 0;
464 ssize_t thread_index = 0, i;
467 ods_log_assert(cmdhandler);
468 ods_log_assert(cmdhandler->
engine);
474 clilen =
sizeof(cliaddr);
476 ret = select(cmdhandler->
listen_fd+1, &rset, NULL, NULL, NULL);
481 for (i = thread_index-1; i>0; i--) {
482 if (!cmdcs[i].stopped)
break;
483 if (pthread_join(cmdcs[i].thread_id, NULL)) {
491 if (errno != EINTR && errno != EWOULDBLOCK) {
497 if (FD_ISSET(cmdhandler->
listen_fd, &rset) &&
501 (
struct sockaddr *) &cliaddr, &clilen);
503 if (errno != EINTR && errno != EWOULDBLOCK) {
511 flags = fcntl(connfd, F_GETFL, 0);
513 ods_log_error(
"[%s] unable to create, fcntl(F_GETFL) failed: %s",
514 module_str, strerror(errno));
518 if (fcntl(connfd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
519 ods_log_error(
"[%s] unable to create, fcntl(F_SETFL) failed: %s",
520 module_str, strerror(errno));
525 cmdc = &cmdcs[thread_index];
532 if (!pthread_create(&(cmdcs[thread_index].thread_id), NULL, &cmdhandler_accept_client,
537 ods_log_debug(
"[%s] %lu clients in progress...", module_str, thread_index);
542 for (i = thread_index-1; i>0; i--) {
543 if (pthread_join(cmdcs[i].thread_id, NULL)) {
560 struct sockaddr_un servaddr;
561 const char* servsock_filename = OPENDNSSEC_ENFORCER_SOCKETFILE;
563 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
566 "socket() failed: %s\n", strerror(errno));
569 bzero(&servaddr,
sizeof(servaddr));
570 servaddr.sun_family = AF_UNIX;
571 strncpy(servaddr.sun_path, servsock_filename,
572 sizeof(servaddr.sun_path) - 1);
574 ret = connect(sockfd, (
const struct sockaddr*) &servaddr,
578 "connect() failed: %s\n", strerror(errno));
583 client_printf(sockfd,
"");
596 ods_log_assert(engine);
602 if (self_pipe_trick() == 0) {
604 ods_log_debug(
"[engine] waiting for command handler to exit...");
608 ods_log_error(
"[engine] command handler self pipe trick failed, " struct cmd_func_block * key_ds_seen_funcblock(void)
struct cmd_func_block * update_conf_funcblock(void)
void cmdhandler_stop(struct engine_struct *engine)
void cmdhandler_get_usage(int sockfd)
void ods_log_debug(const char *format,...)
struct cmd_func_block * signconf_funcblock(void)
struct cmd_func_block * resalt_funcblock(void)
struct cmd_func_block * zonelist_export_funcblock(void)
struct cmd_func_block * key_ds_gone_funcblock(void)
struct cmd_func_block * verbosity_funcblock(void)
struct engine_struct * engine
void ods_fatal_exit(const char *format,...)
int(* run)(int sockfd, struct engine_struct *engine, const char *cmd, ssize_t n, db_connection_t *dbconn)
struct cmd_func_block * key_list_funcblock(void)
void ods_log_error(const char *format,...)
struct cmd_func_block * ctrl_funcblock(void)
struct cmd_func_block * queue_funcblock(void)
void cmdhandler_start(cmdhandler_type *cmdhandler)
struct sockaddr_un listen_addr
struct cmd_func_block * policy_import_funcblock(void)
struct cmd_func_block * enforce_funcblock(void)
#define ODS_SE_MAX_HANDLERS
db_configuration_list_t * dbcfg_list
void(* usage)(int sockfd)
struct cmd_func_block * policy_list_funcblock(void)
struct cmd_func_block * key_generate_funcblock(void)
struct cmd_func_block * help_funcblock(void)
struct cmd_func_block * key_ds_submit_funcblock(void)
struct cmd_func_block * flush_funcblock(void)
struct cmd_func_block * zonelist_import_funcblock(void)
struct cmd_func_block * update_repositorylist_funcblock(void)
struct cmd_func_block * zone_add_funcblock(void)
struct cmd_func_block * key_purge_funcblock(void)
struct cmd_func_block * key_export_funcblock(void)
cmdhandler_type * cmdhandler
db_connection_t * get_database_connection(db_configuration_list_t *dbcfg_list)
struct cmd_func_block * policy_purge_funcblock(void)
struct cmd_func_block * policy_export_funcblock(void)
struct cmd_func_block * repositorylist_funcblock(void)
struct cmd_func_block * get_funcblock(const char *cmd, ssize_t n)
void ods_log_verbose(const char *format,...)
struct cmd_func_block * key_import_funcblock(void)
struct cmd_func_block * time_leap_funcblock(void)
struct cmd_func_block * zone_del_funcblock(void)
struct cmd_func_block * key_rollover_funcblock(void)
struct cmd_func_block * backup_funcblock(void)
cmdhandler_type * cmdhandler_create(const char *filename)
void db_connection_free(db_connection_t *connection)
struct cmd_func_block * key_ds_retract_funcblock(void)
struct cmd_func_block * update_all_funcblock(void)
int(* handles)(const char *cmd, ssize_t n)
struct cmd_func_block * zone_list_funcblock(void)
void ods_log_warning(const char *format,...)
struct cmd_func_block * rollover_list_funcblock(void)
void cmdhandler_cleanup(cmdhandler_type *cmdhandler)
struct cmd_func_block *(* fbgetfunctype)(void)