summaryrefslogtreecommitdiff
path: root/support/dktools/dk4sock33.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4sock33.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk4sock33.ctr')
-rw-r--r--support/dktools/dk4sock33.ctr241
1 files changed, 241 insertions, 0 deletions
diff --git a/support/dktools/dk4sock33.ctr b/support/dktools/dk4sock33.ctr
new file mode 100644
index 0000000000..d6ff6b842e
--- /dev/null
+++ b/support/dktools/dk4sock33.ctr
@@ -0,0 +1,241 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4mai8dus.h"
+#include "dk4mao8d.h"
+
+
+
+$!trace-include
+
+
+
+/** Attempt to convert an IPv4 or IPv6 address from text to address.
+ @param dptr Destination variable.
+ @param str Source text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_c8_find_address(dk4_sockaddr_storage_t *dptr, const char *str)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *in6;
+#endif
+ struct sockaddr_in *in4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR addr6;
+#endif
+ IN_ADDR addr4;
+ int back = 0;
+ int res;
+ $? "+ dk4socket_c8_find_address"
+ res = dk4socket_c8_inet_pton(&addr4, sizeof(addr4), AF_INET, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". IPv4"
+ in4 = (struct sockaddr_in *)dptr;
+ in4->sin_family = AF_INET;
+ DK4_MEMCPY(&(in4->sin_addr), &addr4, sizeof(addr4));
+ back = 1;
+ } else {
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ res = dk4socket_c8_inet_pton(&addr6, sizeof(addr6), AF_INET6, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". IPv6"
+ in6 = (struct sockaddr_in6 *)dptr;
+ in6->sin6_family = AF_INET6;
+ DK4_MEMCPY(&(in6->sin6_addr), &addr6, sizeof(addr6));
+ back = 1;
+ }
+#endif
+ }
+ $? "- dk4socket_c8_find_address %d", back
+ return back;
+}
+
+
+
+/** Find address for one host name.
+ @param dptr Address of destination data structure.
+ @param remhost Remote host name.
+ @param remport Remote port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6 addresses.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_c8_find_host(
+ dk4_sockaddr_storage_t *dptr,
+ const char *remhost,
+ unsigned short remport,
+ int ip4
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ char buf[16*sizeof(unsigned short)];
+ struct addrinfo hints;
+ struct addrinfo *results = NULL;
+ struct addrinfo *rptr = NULL;
+ int back = 0;
+ int res = 0;
+ $? "+ dk4socket_c8_find_host (getaddrinfo) \"%s\"", TR_8STR(remhost)
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)remport, 0, NULL
+ );
+ if (0 != res) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = 0;
+ hints.ai_flags = AI_NUMERICSERV;
+ res = getaddrinfo(remhost, buf, &hints, &results);
+ if ((0 == res) && (NULL != results)) { $? ". getaddrinfo"
+ if (0 != ip4) { $? ". IPv4 preferred"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) { $? ". entry"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (AF_INET == rptr->ai_addr->sa_family) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ } else { $? "! address too large"
+ }
+ } else { $? "! not IPv4"
+ }
+ } else { $? "! no address data"
+ }
+ rptr = rptr->ai_next;
+ }
+ if (0 == back) {
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) { $? ". entry"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ } else { $? "! address too large"
+ }
+ } else { $? "! no address data"
+ }
+ rptr = rptr->ai_next;
+ }
+ }
+ } else { $? ". any address family"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) { $? ". entry"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ } else { $? "! address too large"
+ }
+ } else { $? "! no address data"
+ }
+ rptr = rptr->ai_next;
+ }
+ }
+ } else { $? "! getaddrinfo"
+ }
+ if (NULL != results) { freeaddrinfo(results); }
+ } else { $? "! failed to convert port no to text"
+ }
+ $? "- dk4socket_c8_find_host %d", back
+ return back;
+#else
+#if DK4_HAVE_GETHOSTBYNAME
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *sa6;
+#endif
+ struct sockaddr_in *sa4;
+ struct hostent *hep = NULL;
+ int back = 0;
+ $? "+ dk4socket_c8_find_host (gethostbyname) \"%s\"", TR_8STR(remhost)
+ hep = gethostbyname(remhost);
+ if (NULL != hep) { $? ". entry"
+ if (NULL != hep->h_addr_list) { $? ". list"
+ if (NULL != *(hep->h_addr_list)) { $? ". element"
+ switch (hep->h_addrtype) {
+ case AF_INET : { $? ". IPv4"
+ sa4 = (struct sockaddr_in *)dptr;
+ DK4_MEMRES(sa4, sizeof(struct sockaddr_in));
+ sa4->sin_family = AF_INET;
+ sa4->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa4->sin_addr),*(hep->h_addr_list),sizeof(IN_ADDR));
+ back = 1; $? ". found"
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : { $? ". IPv6"
+ sa6 = (struct sockaddr_in6 *)dptr;
+ DK4_MEMRES(sa6, sizeof(struct sockaddr_in6));
+ sa6->sin6_family = AF_INET6;
+ sa6->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa6->sin6_addr),*(hep->h_addr_list),sizeof(IN6_ADDR));
+ back = 1; $? ". found"
+ } break;
+#endif
+ }
+ } else { $? "! NULL pointer"
+ }
+ } else { $? "! NULL list"
+ }
+ } else { $? "! not found"
+ }
+ $? "- dk4socket_c8_find_host %d", back
+ return back;
+#else
+ int back = 0;
+ $? "+ dk4socket_c8_find_host (none) \"%s\"", TR_8STR(remhost)
+ $? "- dk4socket_c8_find_host %d", back
+ return back;
+#endif
+#endif
+}
+
+
+
+int
+dk4socket_c8_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const char *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ $? "+ dk4socket_c8_udp_addresses_numeric \"%s\"", TR_8STR(remhost)
+ if ((NULL != array) && (NULL != remhost) && (0 < remport) && (0 < locport)) {
+ DK4_MEMRES(array, (2*sizeof(dk4_sockaddr_storage_t)));
+ if (0 != dk4socket_c8_find_address(array, remhost)) {
+ $? ". address found"
+ back = dk4socket_complete_addresses(array, remport, locport);
+ $? ". back = %d", back
+ }
+ if (DK4_SOCKET_RESULT_FAILED == back) { $? ". no addr"
+ if (0 != dk4socket_c8_find_host(array, remhost, remport, ip4)) {
+ back = dk4socket_complete_addresses(array, remport, locport);
+ if (DK4_SOCKET_RESULT_FAILED == back) { $? "! not completed"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else { $? "! host not found"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_udp_addresses_numeric %d", back
+ return back;
+}
+
+