diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Makefile.am | 2 | ||||
-rw-r--r-- | src/lib/python/isc/auth/sqlite3_ds.py | 34 | ||||
-rw-r--r-- | src/lib/xfr/Makefile.am | 31 | ||||
-rw-r--r-- | src/lib/xfr/fd_share.cc | 102 | ||||
-rw-r--r-- | src/lib/xfr/fd_share.h | 19 | ||||
-rw-r--r-- | src/lib/xfr/python_xfr.cc | 38 | ||||
-rw-r--r-- | src/lib/xfr/xfrout_client.cc | 59 | ||||
-rw-r--r-- | src/lib/xfr/xfrout_client.h | 41 |
8 files changed, 325 insertions, 1 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index ed52529fb2..cd262a1d74 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1 +1 @@ -SUBDIRS = exceptions dns cc config auth python +SUBDIRS = exceptions dns cc config auth xfr python diff --git a/src/lib/python/isc/auth/sqlite3_ds.py b/src/lib/python/isc/auth/sqlite3_ds.py index 014494edfc..937c4e7148 100644 --- a/src/lib/python/isc/auth/sqlite3_ds.py +++ b/src/lib/python/isc/auth/sqlite3_ds.py @@ -84,6 +84,40 @@ def open(dbfile): return conn, cur + +######################################################################### +# get_zone_datas +# returns all the records for one zone with the given zone name. +######################################################################### +def get_zone_datas(zonename, dbfile): + conn, cur = open(dbfile) + zone_id = get_zoneid(zonename, cur) + + cur.execute("SELECT * FROM records WHERE zone_id = ?", [zone_id]) + record = cur.fetchone() + while record: + yield record + record = cur.fetchone() + + cur.close() + conn.close() + + +######################################################################### +# get_zone_soa +# returns the soa record of the zone with the given zone name. +# If the zone doesn't exist, return None. +######################################################################### +def get_zone_soa(zonename, dbfile): + conn, cur = open(dbfile) + id = get_zoneid(zonename, cur) + cur.execute("SELECT * FROM records WHERE zone_id = ? and rdtype = ?", [id, 'SOA']) + datas = cur.fetchone() + cur.close() + conn.close() + + return datas + ######################################################################### # get_zoneid: # returns the zone_id for a given zone name, or an empty diff --git a/src/lib/xfr/Makefile.am b/src/lib/xfr/Makefile.am new file mode 100644 index 0000000000..1f481992b4 --- /dev/null +++ b/src/lib/xfr/Makefile.am @@ -0,0 +1,31 @@ +SUBDIRS = . + +AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib +AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns +AM_CPPFLAGS += -I$(top_srcdir)/ext +if GCC_WERROR_OK +AM_CPPFLAGS += -Werror +endif + +CLEANFILES = *.gcno *.gcda + +lib_LTLIBRARIES = libxfr.la +libxfr_la_SOURCES = xfrout_client.h xfrout_client.cc +libxfr_la_SOURCES += fd_share.h fd_share.cc + +if HAVE_BOOST_PYTHON +pyexec_LTLIBRARIES = bind10_xfr.la +bind10_xfr_la_SOURCES = python_xfr.cc fd_share.cc fd_share.h +bind10_xfr_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES) +if GCC_WERROR_OK +# XXX: Boost.Python triggers strict aliasing violation, so if we use -Werror +# we need to suppress the warnings. +bind10_xfr_la_CPPFLAGS += -fno-strict-aliasing +endif +bind10_xfr_la_LDFLAGS = $(BOOST_LDFLAGS) $(PYTHON_LDFLAGS) +# Python prefers .so, while some OSes (specifically MacOS) use a different +# suffix for dynamic objects. -module is necessary to work this around. +bind10_xfr_la_LDFLAGS += -module +bind10_xfr_la_LIBADD = $(BOOST_PYTHON_LIB) $(PYTHON_LIB) +endif + diff --git a/src/lib/xfr/fd_share.cc b/src/lib/xfr/fd_share.cc new file mode 100644 index 0000000000..d8cedb1d49 --- /dev/null +++ b/src/lib/xfr/fd_share.cc @@ -0,0 +1,102 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include "fd_share.h" + +namespace isc { +namespace xfr { + +#define FD_BUFFER_CREATE(n) \ + struct { \ + struct cmsghdr h; \ + int fd[n]; \ + } + +int +send_fds_with_buffer(int sock, const int *fds, unsigned n_fds, void *buffer) +{ + struct msghdr msghdr; + char nothing = '!'; + struct iovec nothing_ptr; + struct cmsghdr *cmsg; + int i; + + nothing_ptr.iov_base = ¬hing; + nothing_ptr.iov_len = 1; + msghdr.msg_name = NULL; + msghdr.msg_namelen = 0; + msghdr.msg_iov = ¬hing_ptr; + msghdr.msg_iovlen = 1; + msghdr.msg_flags = 0; + msghdr.msg_control = buffer; + msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds; + cmsg = CMSG_FIRSTHDR(&msghdr); + cmsg->cmsg_len = msghdr.msg_controllen; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + for(i = 0; i < n_fds; i++) + ((int *)CMSG_DATA(cmsg))[i] = fds[i]; + + int ret = sendmsg(sock, &msghdr, 0); + return (ret >= 0 ? 0 : -1); +} + +int +recv_fds_with_buffer(int sock, int *fds, unsigned n_fds, void *buffer) +{ + struct msghdr msghdr; + char nothing; + struct iovec nothing_ptr; + struct cmsghdr *cmsg; + int i; + + nothing_ptr.iov_base = ¬hing; + nothing_ptr.iov_len = 1; + msghdr.msg_name = NULL; + msghdr.msg_namelen = 0; + msghdr.msg_iov = ¬hing_ptr; + msghdr.msg_iovlen = 1; + msghdr.msg_flags = 0; + msghdr.msg_control = buffer; + msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds; + cmsg = CMSG_FIRSTHDR(&msghdr); + cmsg->cmsg_len = msghdr.msg_controllen; + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + for(i = 0; i < n_fds; i++) + ((int *)CMSG_DATA(cmsg))[i] = -1; + + if(recvmsg(sock, &msghdr, 0) < 0) + return (-1); + + for(i = 0; i < n_fds; i++) { + fds[i] = ((int *)CMSG_DATA(cmsg))[i]; + } + + n_fds = (msghdr.msg_controllen - sizeof(struct cmsghdr)) / sizeof(int); + return n_fds; +} + +int +recv_fd(int sock) +{ + FD_BUFFER_CREATE(1) buffer; + int fd = 0; + int ret = recv_fds_with_buffer(sock, &fd, 1, &buffer); + if (ret == -1) + return -1; + + return fd; +} + +int +send_fd(int sock, int fd) +{ + FD_BUFFER_CREATE(1) buffer; + int ret = send_fds_with_buffer(sock, &fd, 1, &buffer); + return ((ret < 0) ? -1 : ret); +} + +} // End for namespace xfr +} // End for namespace isc diff --git a/src/lib/xfr/fd_share.h b/src/lib/xfr/fd_share.h new file mode 100644 index 0000000000..dd2bf78b3c --- /dev/null +++ b/src/lib/xfr/fd_share.h @@ -0,0 +1,19 @@ +#include <stdlib.h> + +namespace isc { +namespace xfr { + +// Receive socket descriptor on unix domain socket 'sock'. +// Returned value is the socket descriptor received. +// Errors are indicated by a return value of -1. +int +recv_fd(int sock); + +// Send socket descriptor "fd" to server over unix domain socket 'sock', +// the connection from socket 'sock' to unix domain server should be established first. +// Errors are indicated by a return value of -1. +int +send_fd(int sock, int fd); + +} // End for namespace xfr +} // End for namespace isc diff --git a/src/lib/xfr/python_xfr.cc b/src/lib/xfr/python_xfr.cc new file mode 100644 index 0000000000..c7d80654fb --- /dev/null +++ b/src/lib/xfr/python_xfr.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +// $Id: message_python.cc 2010-03-08 18:44:00 feng $ + +#include <string> +#include <boost/python.hpp> +#include <boost/python/class.hpp> +#include <boost/python/module.hpp> +#include <boost/python/def.hpp> +#include <boost/python/exception_translator.hpp> +#include <boost/python/return_internal_reference.hpp> +#include <boost/python/copy_const_reference.hpp> +#include <boost/shared_ptr.hpp> + +#include "fd_share.h" + +using namespace isc::xfr; +using namespace boost::python; + + +BOOST_PYTHON_MODULE(bind10_xfr) +{ + def("recv_fd", &recv_fd); + def("send_fd", &send_fd); +} + diff --git a/src/lib/xfr/xfrout_client.cc b/src/lib/xfr/xfrout_client.cc new file mode 100644 index 0000000000..32cf65715f --- /dev/null +++ b/src/lib/xfr/xfrout_client.cc @@ -0,0 +1,59 @@ +#include <cstdlib> +#include <cstring> +#include <iostream> +#include <boost/asio.hpp> +#include "fd_share.h" +#include "xfrout_client.h" + +using boost::asio::local::stream_protocol; + +namespace isc { +namespace xfr { + +void +XfroutClient::connect() +{ + socket_.connect(stream_protocol::endpoint(file_path_)); +} + +void +XfroutClient::disconnect() +{ + socket_.close(); +} + +void +XfroutClient::sendData(uint8_t *msg_data, uint16_t msg_len) +{ + int count = 0; + while(count < msg_len) { + int size = send(socket_.native(), msg_data + count, msg_len - count, 0); + if (size == -1) + isc_throw(XfroutError, "auth failed to send data to xfrout module\n"); + + count += size; + } + + return; +} + +int +XfroutClient::sendXfroutRequestInfo(int tcp_sock, uint8_t *msg_data, uint16_t msg_len) +{ + if (-1 == send_fd(socket_.native(), tcp_sock)) + isc_throw(XfroutError, "Fail to send socket descriptor to xfrout module\n"); + + sendData((uint8_t *)&msg_len, 2); + sendData(msg_data, msg_len); + + int databuf = 0; + int status = recv(socket_.native(), &databuf, sizeof(int), 0); + if (status != 0) + isc_throw(XfroutError, "xfr query doesn't been processed properly by xfrout module\n"); + + return 0; +} + +} // End for xfr +} // End for isc + diff --git a/src/lib/xfr/xfrout_client.h b/src/lib/xfr/xfrout_client.h new file mode 100644 index 0000000000..f05abd79c5 --- /dev/null +++ b/src/lib/xfr/xfrout_client.h @@ -0,0 +1,41 @@ +#ifndef _XFROUT_CLIENT_H +#define _XFROUT_CLIENT_H + +#include <boost/asio.hpp> +#include <exceptions/exceptions.h> + +namespace isc { +namespace xfr { + +class XfroutError: public Exception +{ +public: + XfroutError(const char *file, size_t line, const char *what): + isc::Exception(file, line, what) {} +}; + +using boost::asio::local::stream_protocol; +class XfroutClient +{ +public: + XfroutClient(const std::string &file): + socket_(io_service_), file_path_(file) {} + + void connect(); + void disconnect(); + int sendXfroutRequestInfo(int tcp_sock, uint8_t *msg_data, uint16_t msg_len); + +private: + void sendData(uint8_t *msg_data, uint16_t msg_len); + +private: + boost::asio::io_service io_service_; + // The socket used to communicate with the xfrout server. + stream_protocol::socket socket_; + const std::string file_path_; +}; + +} // End for namespace xfr +} // End for namespace isc + +#endif |