From 1cec318025eea0480e420f781edba1156dbb61fa Mon Sep 17 00:00:00 2001 From: Xnoe Date: Tue, 10 Jan 2023 21:47:02 +0000 Subject: [PATCH] Initial commit. --- .editorconfig | 10 ++++++ Dockerfile | 10 ++++++ Makefile | 9 +++++ docker-compose.yml | 4 +++ rdns--1.0.sql | 9 +++++ rdns.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ rdns.control | 3 ++ 7 files changed, 134 insertions(+) create mode 100644 .editorconfig create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 docker-compose.yml create mode 100644 rdns--1.0.sql create mode 100644 rdns.c create mode 100644 rdns.control diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a943b82 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +indent_size = 2 +indent_style = space +end_of_line = lf +insert_final_newline = true + +[Makefile] +indent_style = tab diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..59f1e57 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM postgres:14 + +RUN apt-get update +RUN apt-get install -y build-essential +RUN apt-get install -y postgresql-server-dev-14 +COPY rdns.c Makefile rdns.control rdns--1.0.sql /usr/src/rdns/ +RUN cd /usr/src/rdns/; \ + make; \ + make install; \ + echo "shared_preload_libraries = 'rdns'" >> $PGDATA/postgresql.conf; diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b9123ee --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +OBJS = rdns.o + +EXTENSION = rdns +DATA = rdns--1.0.sql +MODULES = rdns + +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6850867 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,4 @@ +services: + postgres: + build: . + image: registry.xnopyt.com/postgres-rdns:14 diff --git a/rdns--1.0.sql b/rdns--1.0.sql new file mode 100644 index 0000000..6a01ea6 --- /dev/null +++ b/rdns--1.0.sql @@ -0,0 +1,9 @@ +CREATE FUNCTION rdns_lookup(text) +RETURNS text +AS '$libdir/rdns' +LANGUAGE C STRICT; + +CREATE FUNCTION circular_rdns_lookup(text) +RETURNS text +AS '$libdir/rdns' +LANGUAGE C STRICT; diff --git a/rdns.c b/rdns.c new file mode 100644 index 0000000..5ffacfe --- /dev/null +++ b/rdns.c @@ -0,0 +1,89 @@ +#include "postgres.h" +#include "fmgr.h" +#include "utils/builtins.h" +#include +#include +#include +#include + +PG_MODULE_MAGIC; + + +PG_FUNCTION_INFO_V1(rdns_lookup); +Datum rdns_lookup(PG_FUNCTION_ARGS) { + struct in_addr iaddr; + char host[512]; + struct sockaddr_in sa; + int r; + char* ip = text_to_cstring(PG_GETARG_TEXT_PP(0)); + + memset(&iaddr, 0, sizeof(struct in_addr)); + memset(&sa, 0, sizeof(struct sockaddr_in)); + memset(host, 0, 512); + + inet_aton(ip, &iaddr); + + sa.sin_family = AF_INET; + sa.sin_addr = iaddr; + + r = getnameinfo((struct sockaddr*)(&sa), sizeof(struct sockaddr_in), host, 512, 0, 0, NI_NAMEREQD); + if (r == EAI_NONAME) + PG_RETURN_NULL(); + if (r) { + ereport(ERROR, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("getnameinfo failed! %s", gai_strerror(r)))); + } + + PG_RETURN_TEXT_P(cstring_to_text(host)); +} + +PG_FUNCTION_INFO_V1(circular_rdns_lookup); +Datum circular_rdns_lookup(PG_FUNCTION_ARGS) { + struct in_addr iaddr; + char host[512]; + struct sockaddr_in sa; + int r; + struct addrinfo hint; + struct addrinfo* results; + char* ip = text_to_cstring(PG_GETARG_TEXT_PP(0)); + struct addrinfo* c; + + memset(&iaddr, 0, sizeof(struct in_addr)); + memset(&sa, 0, sizeof(struct sockaddr_in)); + memset(host, 0, 512); + memset(&hint, 0, sizeof(struct addrinfo)); + + inet_aton(ip, &iaddr); + + sa.sin_family = AF_INET; + sa.sin_addr = iaddr; + + r = getnameinfo((struct sockaddr*)(&sa), sizeof(struct sockaddr_in), host, 512, 0, 0, NI_NAMEREQD); + if (r == EAI_NONAME) + PG_RETURN_NULL(); + if (r) { + ereport(ERROR, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("getnameinfo failed! %s", gai_strerror(r)))); + } + + hint.ai_family = AF_INET; + + r = getaddrinfo(host, 0, &hint, &results); + if (r) { + ereport(ERROR, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("getaddrinfo failed! %s", gai_strerror(r)))); + } + + c = results; + while (c) { + struct addrinfo* current = c; + c = current->ai_next; + if (current->ai_family != AF_INET) + continue; + + if (((struct sockaddr_in*)current->ai_addr)->sin_addr.s_addr == iaddr.s_addr) { + freeaddrinfo(results); + PG_RETURN_TEXT_P(cstring_to_text(host)); + } + } + + freeaddrinfo(results); + PG_RETURN_NULL(); +} diff --git a/rdns.control b/rdns.control new file mode 100644 index 0000000..57e5678 --- /dev/null +++ b/rdns.control @@ -0,0 +1,3 @@ +comment = 'Reverse DNS Extension for PostgreSQL' +default_version = '1.0' +relocatable = true