Commit c1711933 authored by Marek Vavrusa's avatar Marek Vavrusa

Implemented remote sockets, not in configuration yet.

refs #2035
parent 8683e18f
......@@ -134,6 +134,8 @@ src/knot/main.c
src/knot/ctl/knotc_main.c
src/knot/ctl/process.c
src/knot/ctl/process.h
src/knot/ctl/remote.c
src/knot/ctl/remote.h
src/knot/other/debug.h
src/knot/other/error.c
src/knot/other/error.h
......
......@@ -285,6 +285,8 @@ libknotd_la_SOURCES = \
knot/conf/conf.h \
knot/ctl/process.c \
knot/ctl/process.h \
knot/ctl/remote.c \
knot/ctl/remote.h \
knot/server/dthreads.c \
knot/server/journal.c \
knot/server/socket.c \
......
......@@ -19,84 +19,8 @@
#include <unistd.h>
#include <config.h>
/* OpenBSD compatibility. */
#ifndef HAVE_PSELECT
/*
* Like select(2) but set the signals to block while waiting in
* select. This version is not entirely race condition safe. Only
* operating system support can make it so.
*
* Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/time.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <unistd.h>
#include <signal.h>
static int
pselect (int n,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
const struct timespec *timeout,
const sigset_t *sigmask)
{
int result;
sigset_t saved_sigmask;
struct timeval saved_timeout;
if (sigmask && sigprocmask(SIG_SETMASK, sigmask, &saved_sigmask) == -1)
return -1;
if (timeout) {
saved_timeout.tv_sec = timeout->tv_sec;
saved_timeout.tv_usec = timeout->tv_nsec / 1000;
result = select(n, readfds, writefds, exceptfds, &saved_timeout);
} else {
result = select(n, readfds, writefds, exceptfds, NULL);
}
if (sigmask && sigprocmask(SIG_SETMASK, &saved_sigmask, NULL) == -1)
return -1;
return result;
}
#endif
#include "common/evqueue.h"
#include "common/fdset.h"
/*! \brief Singleton application-wide event queue. */
evqueue_t *s_evqueue = 0;
......@@ -148,7 +72,8 @@ int evqueue_poll(evqueue_t *q, const struct timespec *ts,
FD_SET(q->fds[EVQUEUE_READFD], &rfds);
/* Wait for events. */
int ret = pselect(q->fds[EVQUEUE_READFD] + 1, &rfds, 0, 0, ts, sigmask);
int ret = fdset_pselect(q->fds[EVQUEUE_READFD] + 1, &rfds,
0, 0, ts, sigmask);
if (ret < 0) {
return -1;
}
......
......@@ -203,3 +203,86 @@ int fdset_sweep(fdset_t* fdset, void(*cb)(fdset_t*, int, void*), void *data)
return sweeped;
}
/* OpenBSD compatibility. */
#ifndef HAVE_PSELECT
/*
* Like select(2) but set the signals to block while waiting in
* select. This version is not entirely race condition safe. Only
* operating system support can make it so.
*
* Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/time.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <unistd.h>
#include <signal.h>
static int
pselect (int n,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
const struct timespec *timeout,
const sigset_t *sigmask)
{
int result;
sigset_t saved_sigmask;
struct timeval saved_timeout;
if (sigmask && sigprocmask(SIG_SETMASK, sigmask, &saved_sigmask) == -1)
return -1;
if (timeout) {
saved_timeout.tv_sec = timeout->tv_sec;
saved_timeout.tv_usec = timeout->tv_nsec / 1000;
result = select(n, readfds, writefds, exceptfds, &saved_timeout);
} else {
result = select(n, readfds, writefds, exceptfds, NULL);
}
if (sigmask && sigprocmask(SIG_SETMASK, &saved_sigmask, NULL) == -1)
return -1;
return result;
}
#endif
int fdset_pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask)
{
return pselect(n, readfds, writefds, exceptfds, timeout, sigmask);
}
......@@ -232,6 +232,20 @@ int fdset_set_watchdog(fdset_t* fdset, int fd, int interval);
*/
int fdset_sweep(fdset_t* fdset, void(*cb)(fdset_t*, int, void*), void *data);
/*!
* \brief pselect(2) compatibility wrapper.
* \param n Number of file descriptors.
* \param readfds Array of fds to read.
* \param writefds Array of fds to write.
* \param exceptfds Array of fds for exceptions.
* \param timeout Upper bound of time elapsed.
* \param sigmask If != NULL, replaces current signal mask.
* \return Number of events or -1 if fails.
*/
int fdset_pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask);
#endif /* _KNOTD_FDSET_H_ */
/*! @} */
......@@ -418,6 +418,7 @@ conf_t *conf_new(const char* path)
init_list(&c->hooks);
init_list(&c->remotes);
init_list(&c->keys);
init_list(&c->ctl.allow);
// Defaults
c->zone_checks = 0;
......
......@@ -143,6 +143,14 @@ typedef struct conf_key_t {
knot_key_t k;
} conf_key_t;
/*!
* \brief Remote control interface.
*/
typedef struct conf_control_t {
conf_iface_t *iface; /*!< Remote control interface. */
list allow; /*!< List of allowed remotes. */
} conf_control_t;
/*!
* \brief Main config structure.
*
......@@ -199,6 +207,11 @@ typedef struct conf_t {
int dbsync_timeout; /*!< Default interval between syncing to zonefile.*/
size_t ixfr_fslimit; /*!< File size limit for IXFR journal. */
int build_diffs; /*!< Calculate differences from changes. */
/*
* Remote control interface.
*/
conf_control_t ctl;
/*
* Implementation specifics
......
......@@ -31,9 +31,11 @@
#include "knot/other/error.h"
#include "knot/server/server.h"
#include "knot/ctl/process.h"
#include "knot/ctl/remote.h"
#include "knot/conf/conf.h"
#include "knot/conf/logconf.h"
#include "knot/server/zones.h"
#include "knot/server/tcp-handler.h"
/*----------------------------------------------------------------------------*/
......@@ -301,10 +303,13 @@ int main(int argc, char **argv)
sa.sa_flags = 0;
pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL);
/* Bind to control interface. */
int remote = remote_bind(conf()->ctl.iface);
/* Run event loop. */
for(;;) {
pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
int ret = evqueue_poll(evqueue(), 0, 0);
int ret = remote_poll(remote);
pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL);
/* Interrupts. */
......@@ -333,6 +338,9 @@ int main(int argc, char **argv)
"reload failed.\n");
break;
}
/*! \todo Close and bind to new remote control. */
/*! \todo What if remotely requests reload, it will close the conn? */
}
if (sig_req_refresh) {
log_server_info("Refreshing slave zones...\n");
......@@ -348,17 +356,38 @@ int main(int argc, char **argv)
/* Events. */
if (ret > 0) {
event_t ev;
if (evqueue_get(evqueue(), &ev) == 0) {
dbg_server_verb("Event: "
"received new event.\n");
if (ev.cb) {
ev.cb(&ev);
}
int c = tcp_accept(remote);
if (c < 0) {
continue;
}
/*! \todo Temporary */
uint8_t buf[1024] = {0};
size_t buflen = sizeof(buf);
sockaddr_t addr;
sockaddr_init(&addr, AF_INET);
int r = tcp_recv(c, buf, buflen, &addr);
if (r < 0) {
close(c);
continue;
}
char straddr[SOCKADDR_STRLEN];
sockaddr_tostr(&addr, straddr, sizeof(straddr));
fprintf(stderr, "remote: accepted %d bytes from %s:%d\n",
r, straddr, sockaddr_portnum(&addr));
close(c);
}
}
pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
/* Close remote control interface */
if (remote > -1) {
close(remote);
remote = -1;
}
if ((server_wait(server)) != KNOTD_EOK) {
log_server_error("An error occured while "
......
......@@ -203,4 +203,3 @@ int socket_close(int socket)
return KNOTD_EOK;
}
......@@ -114,7 +114,6 @@ int socket_listen(int fd, int backlog_size);
*/
int socket_close(int fd);
#endif // _KNOTD_SOCKET_H_
/*! @} */
......@@ -296,7 +296,7 @@ static int tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxlen
return res;
}
static int tcp_accept(int fd)
int tcp_accept(int fd)
{
/* Accept incoming connection. */
int incoming = accept(fd, 0, 0);
......
......@@ -42,6 +42,15 @@
#define TCP_ACTIVITY_WD 60 /* [secs] of allowed inactivity between requests */
#define TCP_SWEEP_INTERVAL 2 /* [secs] granularity of connection sweeping */
/*!
* \brief Accept a TCP connection.
* \param fd Associated socket.
*
* \retval Created connection fd if success.
* \retval <0 on error.
*/
int tcp_accept(int fd);
/*!
* \brief Send TCP message.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment