File ucspi-tcp-0.88-ipv6.patch of Package ucspi-tcp
(C) 2012 Peter Conrad <conrad@quisquis.de>
Licensed under the terms and conditions of the GNU General Public License
(version 2). See http://www.gnu.org/licenses/old-licenses/gpl-2.0 .
--- ucspi-tcp-0.88/dns_dfd.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_dfd.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,69 +0,0 @@
-#include "error.h"
-#include "alloc.h"
-#include "byte.h"
-#include "dns.h"
-
-int dns_domain_fromdot(char **out,char *buf,unsigned int n)
-{
- char label[63];
- unsigned int labellen = 0; /* <= sizeof label */
- char name[255];
- unsigned int namelen = 0; /* <= sizeof name */
- char ch;
- char *x;
-
- errno = error_proto;
-
- for (;;) {
- if (!n) break;
- ch = *buf++; --n;
- if (ch == '.') {
- if (labellen) {
- if (namelen + labellen + 1 > sizeof name) return 0;
- name[namelen++] = labellen;
- byte_copy(name + namelen,labellen,label);
- namelen += labellen;
- labellen = 0;
- }
- continue;
- }
- if (ch == '\\') {
- if (!n) break;
- ch = *buf++; --n;
- if ((ch >= '0') && (ch <= '7')) {
- ch -= '0';
- if (n && (*buf >= '0') && (*buf <= '7')) {
- ch <<= 3;
- ch += *buf - '0';
- ++buf; --n;
- if (n && (*buf >= '0') && (*buf <= '7')) {
- ch <<= 3;
- ch += *buf - '0';
- ++buf; --n;
- }
- }
- }
- }
- if (labellen >= sizeof label) return 0;
- label[labellen++] = ch;
- }
-
- if (labellen) {
- if (namelen + labellen + 1 > sizeof name) return 0;
- name[namelen++] = labellen;
- byte_copy(name + namelen,labellen,label);
- namelen += labellen;
- labellen = 0;
- }
-
- if (namelen + 1 > sizeof name) return 0;
- name[namelen++] = 0;
-
- x = alloc(namelen);
- if (!x) return 0;
- byte_copy(x,namelen,name);
-
- if (*out) alloc_free(*out);
- *out = x;
- return 1;
-}
diff -rNU3 ucspi-tcp-0.88/dns_dtda.c ucspi-tcp-0.88.ipv6/dns_dtda.c
--- ucspi-tcp-0.88/dns_dtda.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_dtda.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,35 +0,0 @@
-#include "stralloc.h"
-#include "dns.h"
-
-int dns_domain_todot_cat(stralloc *out,char *d)
-{
- char ch;
- char ch2;
- unsigned char ch3;
- char buf[4];
-
- if (!*d)
- return stralloc_append(out,".");
-
- for (;;) {
- ch = *d++;
- while (ch--) {
- ch2 = *d++;
- if ((ch2 >= 'A') && (ch2 <= 'Z'))
- ch2 += 32;
- if (((ch2 >= 'a') && (ch2 <= 'z')) || ((ch2 >= '0') && (ch2 <= '9')) || (ch2 == '-') || (ch2 == '_')) {
- if (!stralloc_append(out,&ch2)) return 0;
- }
- else {
- ch3 = ch2;
- buf[3] = '0' + (ch3 & 7); ch3 >>= 3;
- buf[2] = '0' + (ch3 & 7); ch3 >>= 3;
- buf[1] = '0' + (ch3 & 7);
- buf[0] = '\\';
- if (!stralloc_catb(out,buf,4)) return 0;
- }
- }
- if (!*d) return 1;
- if (!stralloc_append(out,".")) return 0;
- }
-}
diff -rNU3 ucspi-tcp-0.88/dns.h ucspi-tcp-0.88.ipv6/dns.h
--- ucspi-tcp-0.88/dns.h 2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns.h 2012-02-17 14:06:29.000000000 +0100
@@ -2,83 +2,15 @@
#define DNS_H
#include "stralloc.h"
-#include "iopause.h"
-#include "taia.h"
#define DNS_C_IN "\0\1"
-#define DNS_C_ANY "\0\377"
-#define DNS_T_A "\0\1"
-#define DNS_T_NS "\0\2"
-#define DNS_T_CNAME "\0\5"
-#define DNS_T_SOA "\0\6"
-#define DNS_T_PTR "\0\14"
-#define DNS_T_HINFO "\0\15"
-#define DNS_T_MX "\0\17"
#define DNS_T_TXT "\0\20"
-#define DNS_T_RP "\0\21"
-#define DNS_T_SIG "\0\30"
-#define DNS_T_KEY "\0\31"
-#define DNS_T_AAAA "\0\34"
-#define DNS_T_AXFR "\0\374"
-#define DNS_T_ANY "\0\377"
-
-struct dns_transmit {
- char *query; /* 0, or dynamically allocated */
- unsigned int querylen;
- char *packet; /* 0, or dynamically allocated */
- unsigned int packetlen;
- int s1; /* 0, or 1 + an open file descriptor */
- int tcpstate;
- unsigned int udploop;
- unsigned int curserver;
- struct taia deadline;
- unsigned int pos;
- char *servers;
- char localip[4];
- char qtype[2];
-} ;
-extern void dns_random_init(char *);
-extern unsigned int dns_random(unsigned int);
-
-extern void dns_sortip(char *,unsigned int);
-
-extern void dns_domain_free(char **);
extern int dns_domain_copy(char **,char *);
-extern unsigned int dns_domain_length(char *);
-extern int dns_domain_equal(char *,char *);
-extern char *dns_domain_suffix(char *,char *);
-extern int dns_domain_fromdot(char **,char *,unsigned int);
-extern int dns_domain_todot_cat(stralloc *,char *);
-
extern unsigned int dns_packet_copy(char *,unsigned int,unsigned int,char *,unsigned int);
-extern unsigned int dns_packet_getname(char *,unsigned int,unsigned int,char **);
extern unsigned int dns_packet_skipname(char *,unsigned int,unsigned int);
-extern int dns_packet_nameequal(char *,unsigned int,unsigned int,char *,unsigned int,unsigned int);
-extern int dns_transmit_start(struct dns_transmit *,char *,int,char *,char *,char *);
-extern void dns_transmit_free(struct dns_transmit *);
-extern void dns_transmit_io(struct dns_transmit *,iopause_fd *,struct taia *);
-extern int dns_transmit_get(struct dns_transmit *,iopause_fd *,struct taia *);
-
-extern int dns_resolvconfip(char *);
-extern int dns_resolve(char *,char *);
-extern struct dns_transmit dns_resolve_tx;
-
-extern int dns_ip4_packet(stralloc *,char *,unsigned int);
-extern int dns_ip4(stralloc *,stralloc *);
-extern int dns_name_packet(stralloc *,char *,unsigned int);
-extern void dns_name4_domain(char *,char *);
-#define DNS_NAME4_DOMAIN 31
-extern int dns_name4(stralloc *,char *);
-extern int dns_txt_packet(stralloc *,char *,unsigned int);
extern int dns_txt(stralloc *,stralloc *);
-extern int dns_mx_packet(stralloc *,char *,unsigned int);
-extern int dns_mx(stralloc *,stralloc *);
-
-extern int dns_resolvconfrewrite(stralloc *);
-extern int dns_ip4_qualify_rules(stralloc *,stralloc *,stralloc *,stralloc *);
-extern int dns_ip4_qualify(stralloc *,stralloc *,stralloc *);
#endif
diff -rNU3 ucspi-tcp-0.88/dns_ip.c ucspi-tcp-0.88.ipv6/dns_ip.c
--- ucspi-tcp-0.88/dns_ip.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_ip.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,75 +0,0 @@
-#include "stralloc.h"
-#include "uint16.h"
-#include "byte.h"
-#include "dns.h"
-
-int dns_ip4_packet(stralloc *out,char *buf,unsigned int len)
-{
- unsigned int pos;
- char header[12];
- uint16 numanswers;
- uint16 datalen;
-
- if (!stralloc_copys(out,"")) return -1;
-
- pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1;
- uint16_unpack_big(header + 6,&numanswers);
- pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1;
- pos += 4;
-
- while (numanswers--) {
- pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1;
- pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1;
- uint16_unpack_big(header + 8,&datalen);
- if (byte_equal(header,2,DNS_T_A))
- if (byte_equal(header + 2,2,DNS_C_IN))
- if (datalen == 4) {
- if (!dns_packet_copy(buf,len,pos,header,4)) return -1;
- if (!stralloc_catb(out,header,4)) return -1;
- }
- pos += datalen;
- }
-
- dns_sortip(out->s,out->len);
- return 0;
-}
-
-static char *q = 0;
-
-int dns_ip4(stralloc *out,stralloc *fqdn)
-{
- unsigned int i;
- char code;
- char ch;
-
- if (!stralloc_copys(out,"")) return -1;
- code = 0;
- for (i = 0;i <= fqdn->len;++i) {
- if (i < fqdn->len)
- ch = fqdn->s[i];
- else
- ch = '.';
-
- if ((ch == '[') || (ch == ']')) continue;
- if (ch == '.') {
- if (!stralloc_append(out,&code)) return -1;
- code = 0;
- continue;
- }
- if ((ch >= '0') && (ch <= '9')) {
- code *= 10;
- code += ch - '0';
- continue;
- }
-
- if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1;
- if (dns_resolve(q,DNS_T_A) == -1) return -1;
- if (dns_ip4_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1;
- dns_transmit_free(&dns_resolve_tx);
- dns_domain_free(&q);
- return 0;
- }
-
- out->len &= ~3;
- return 0;
-}
diff -rNU3 ucspi-tcp-0.88/dns_ipq.c ucspi-tcp-0.88.ipv6/dns_ipq.c
--- ucspi-tcp-0.88/dns_ipq.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_ipq.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,71 +0,0 @@
-#include "stralloc.h"
-#include "case.h"
-#include "byte.h"
-#include "str.h"
-#include "dns.h"
-
-static int doit(stralloc *work,char *rule)
-{
- char ch;
- unsigned int colon;
- unsigned int prefixlen;
-
- ch = *rule++;
- if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1;
- colon = str_chr(rule,':');
- if (!rule[colon]) return 1;
-
- if (work->len < colon) return 1;
- prefixlen = work->len - colon;
- if ((ch == '=') && prefixlen) return 1;
- if (case_diffb(rule,colon,work->s + prefixlen)) return 1;
- if (ch == '?') {
- if (byte_chr(work->s,prefixlen,'.') < prefixlen) return 1;
- if (byte_chr(work->s,prefixlen,'[') < prefixlen) return 1;
- if (byte_chr(work->s,prefixlen,']') < prefixlen) return 1;
- }
-
- work->len = prefixlen;
- if (ch == '-') work->len = 0;
- return stralloc_cats(work,rule + colon + 1);
-}
-
-int dns_ip4_qualify_rules(stralloc *out,stralloc *fqdn,stralloc *in,stralloc *rules)
-{
- unsigned int i;
- unsigned int j;
- unsigned int plus;
- unsigned int fqdnlen;
-
- if (!stralloc_copy(fqdn,in)) return -1;
-
- for (j = i = 0;j < rules->len;++j)
- if (!rules->s[j]) {
- if (!doit(fqdn,rules->s + i)) return -1;
- i = j + 1;
- }
-
- fqdnlen = fqdn->len;
- plus = byte_chr(fqdn->s,fqdnlen,'+');
- if (plus >= fqdnlen)
- return dns_ip4(out,fqdn);
-
- i = plus + 1;
- for (;;) {
- j = byte_chr(fqdn->s + i,fqdnlen - i,'+');
- byte_copy(fqdn->s + plus,j,fqdn->s + i);
- fqdn->len = plus + j;
- if (dns_ip4(out,fqdn) == -1) return -1;
- if (out->len) return 0;
- i += j;
- if (i >= fqdnlen) return 0;
- ++i;
- }
-}
-
-int dns_ip4_qualify(stralloc *out,stralloc *fqdn,stralloc *in)
-{
- static stralloc rules;
- if (dns_resolvconfrewrite(&rules) == -1) return -1;
- return dns_ip4_qualify_rules(out,fqdn,in,&rules);
-}
diff -rNU3 ucspi-tcp-0.88/dns_name.c ucspi-tcp-0.88.ipv6/dns_name.c
--- ucspi-tcp-0.88/dns_name.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_name.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,48 +0,0 @@
-#include "stralloc.h"
-#include "uint16.h"
-#include "byte.h"
-#include "dns.h"
-
-static char *q = 0;
-
-int dns_name_packet(stralloc *out,char *buf,unsigned int len)
-{
- unsigned int pos;
- char header[12];
- uint16 numanswers;
- uint16 datalen;
-
- if (!stralloc_copys(out,"")) return -1;
-
- pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1;
- uint16_unpack_big(header + 6,&numanswers);
- pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1;
- pos += 4;
-
- while (numanswers--) {
- pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1;
- pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1;
- uint16_unpack_big(header + 8,&datalen);
- if (byte_equal(header,2,DNS_T_PTR))
- if (byte_equal(header + 2,2,DNS_C_IN)) {
- if (!dns_packet_getname(buf,len,pos,&q)) return -1;
- if (!dns_domain_todot_cat(out,q)) return -1;
- return 0;
- }
- pos += datalen;
- }
-
- return 0;
-}
-
-int dns_name4(stralloc *out,char ip[4])
-{
- char name[DNS_NAME4_DOMAIN];
-
- dns_name4_domain(name,ip);
- if (dns_resolve(name,DNS_T_PTR) == -1) return -1;
- if (dns_name_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1;
- dns_transmit_free(&dns_resolve_tx);
- dns_domain_free(&q);
- return 0;
-}
diff -rNU3 ucspi-tcp-0.88/dns_nd.c ucspi-tcp-0.88.ipv6/dns_nd.c
--- ucspi-tcp-0.88/dns_nd.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_nd.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,24 +0,0 @@
-#include "byte.h"
-#include "fmt.h"
-#include "dns.h"
-
-void dns_name4_domain(char name[DNS_NAME4_DOMAIN],char ip[4])
-{
- unsigned int namelen;
- unsigned int i;
-
- namelen = 0;
- i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[3]);
- name[namelen++] = i;
- namelen += i;
- i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[2]);
- name[namelen++] = i;
- namelen += i;
- i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[1]);
- name[namelen++] = i;
- namelen += i;
- i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[0]);
- name[namelen++] = i;
- namelen += i;
- byte_copy(name + namelen,14,"\7in-addr\4arpa\0");
-}
diff -rNU3 ucspi-tcp-0.88/dns_packet.c ucspi-tcp-0.88.ipv6/dns_packet.c
--- ucspi-tcp-0.88/dns_packet.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_packet.c 2012-02-17 14:00:31.000000000 +0100
@@ -2,6 +2,7 @@
DNS should have used LZ77 instead of its own sophomoric compression algorithm.
*/
+#include "byte.h"
#include "error.h"
#include "dns.h"
diff -rNU3 ucspi-tcp-0.88/dns_random.c ucspi-tcp-0.88.ipv6/dns_random.c
--- ucspi-tcp-0.88/dns_random.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_random.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,65 +0,0 @@
-#include "dns.h"
-#include "taia.h"
-#include "uint32.h"
-#include <sys/types.h>
-#include <unistd.h>
-
-
-static uint32 seed[32];
-static uint32 in[12];
-static uint32 out[8];
-static int outleft = 0;
-
-#define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b))))
-#define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b));
-
-static void surf(void)
-{
- uint32 t[12]; uint32 x; uint32 sum = 0;
- int r; int i; int loop;
-
- for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i];
- for (i = 0;i < 8;++i) out[i] = seed[24 + i];
- x = t[11];
- for (loop = 0;loop < 2;++loop) {
- for (r = 0;r < 16;++r) {
- sum += 0x9e3779b9;
- MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13)
- MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13)
- MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13)
- }
- for (i = 0;i < 8;++i) out[i] ^= t[i + 4];
- }
-}
-
-void dns_random_init(char data[128])
-{
- int i;
- struct taia t;
- char tpack[16];
-
- for (i = 0;i < 32;++i)
- uint32_unpack(data + 4 * i,seed + i);
-
- taia_now(&t);
- taia_pack(tpack,&t);
- for (i = 0;i < 4;++i)
- uint32_unpack(tpack + 4 * i,in + 4 + i);
-
- in[8] = getpid();
- in[9] = getppid();
- /* more space in 10 and 11, but this is probably enough */
-}
-
-unsigned int dns_random(unsigned int n)
-{
- if (!n) return 0;
-
- if (!outleft) {
- if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
- surf();
- outleft = 8;
- }
-
- return out[--outleft] % n;
-}
diff -rNU3 ucspi-tcp-0.88/dns_rcip.c ucspi-tcp-0.88.ipv6/dns_rcip.c
--- ucspi-tcp-0.88/dns_rcip.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_rcip.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,82 +0,0 @@
-#include "taia.h"
-#include "openreadclose.h"
-#include "byte.h"
-#include "ip4.h"
-#include "env.h"
-#include "dns.h"
-
-static stralloc data = {0};
-
-static int init(char ip[64])
-{
- int i;
- int j;
- int iplen = 0;
- char *x;
-
- x = env_get("DNSCACHEIP");
- if (x)
- while (iplen <= 60)
- if (*x == '.')
- ++x;
- else {
- i = ip4_scan(x,ip + iplen);
- if (!i) break;
- x += i;
- iplen += 4;
- }
-
- if (!iplen) {
- i = openreadclose("/etc/resolv.conf",&data,64);
- if (i == -1) return -1;
- if (i) {
- if (!stralloc_append(&data,"\n")) return -1;
- i = 0;
- for (j = 0;j < data.len;++j)
- if (data.s[j] == '\n') {
- if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) {
- i += 10;
- while ((data.s[i] == ' ') || (data.s[i] == '\t'))
- ++i;
- if (iplen <= 60)
- if (ip4_scan(data.s + i,ip + iplen))
- iplen += 4;
- }
- i = j + 1;
- }
- }
- }
-
- if (!iplen) {
- byte_copy(ip,4,"\177\0\0\1");
- iplen = 4;
- }
- byte_zero(ip + iplen,64 - iplen);
- return 0;
-}
-
-static int ok = 0;
-static unsigned int uses;
-static struct taia deadline;
-static char ip[64]; /* defined if ok */
-
-int dns_resolvconfip(char s[64])
-{
- struct taia now;
-
- taia_now(&now);
- if (taia_less(&deadline,&now)) ok = 0;
- if (!uses) ok = 0;
-
- if (!ok) {
- if (init(ip) == -1) return -1;
- taia_uint(&deadline,600);
- taia_add(&deadline,&now,&deadline);
- uses = 10000;
- ok = 1;
- }
-
- --uses;
- byte_copy(s,64,ip);
- return 0;
-}
diff -rNU3 ucspi-tcp-0.88/dns_rcrw.c ucspi-tcp-0.88.ipv6/dns_rcrw.c
--- ucspi-tcp-0.88/dns_rcrw.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_rcrw.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,131 +0,0 @@
-#include "taia.h"
-#include "env.h"
-#include "byte.h"
-#include "str.h"
-#include "openreadclose.h"
-#include "dns.h"
-#include <unistd.h>
-
-static stralloc data = {0};
-
-static int init(stralloc *rules)
-{
- char host[256];
- char *x;
- int i;
- int j;
- int k;
-
- if (!stralloc_copys(rules,"")) return -1;
-
- x = env_get("DNSREWRITEFILE");
- if (!x) x = "/etc/dnsrewrite";
-
- i = openreadclose(x,&data,64);
- if (i == -1) return -1;
-
- if (i) {
- if (!stralloc_append(&data,"\n")) return -1;
- i = 0;
- for (j = 0;j < data.len;++j)
- if (data.s[j] == '\n') {
- if (!stralloc_catb(rules,data.s + i,j - i)) return -1;
- while (rules->len) {
- if (rules->s[rules->len - 1] != ' ')
- if (rules->s[rules->len - 1] != '\t')
- if (rules->s[rules->len - 1] != '\r')
- break;
- --rules->len;
- }
- if (!stralloc_0(rules)) return -1;
- i = j + 1;
- }
- return 0;
- }
-
- x = env_get("LOCALDOMAIN");
- if (x) {
- if (!stralloc_copys(&data,x)) return -1;
- if (!stralloc_append(&data," ")) return -1;
- if (!stralloc_copys(rules,"?:")) return -1;
- i = 0;
- for (j = 0;j < data.len;++j)
- if (data.s[j] == ' ') {
- if (!stralloc_cats(rules,"+.")) return -1;
- if (!stralloc_catb(rules,data.s + i,j - i)) return -1;
- i = j + 1;
- }
- if (!stralloc_0(rules)) return -1;
- if (!stralloc_cats(rules,"*.:")) return -1;
- if (!stralloc_0(rules)) return -1;
- return 0;
- }
-
- i = openreadclose("/etc/resolv.conf",&data,64);
- if (i == -1) return -1;
-
- if (i) {
- if (!stralloc_append(&data,"\n")) return -1;
- i = 0;
- for (j = 0;j < data.len;++j)
- if (data.s[j] == '\n') {
- if (byte_equal("search ",7,data.s + i) || byte_equal("search\t",7,data.s + i) || byte_equal("domain ",7,data.s + i) || byte_equal("domain\t",7,data.s + i)) {
- if (!stralloc_copys(rules,"?:")) return -1;
- i += 7;
- while (i < j) {
- k = byte_chr(data.s + i,j - i,' ');
- k = byte_chr(data.s + i,k,'\t');
- if (!k) { ++i; continue; }
- if (!stralloc_cats(rules,"+.")) return -1;
- if (!stralloc_catb(rules,data.s + i,k)) return -1;
- i += k;
- }
- if (!stralloc_0(rules)) return -1;
- if (!stralloc_cats(rules,"*.:")) return -1;
- if (!stralloc_0(rules)) return -1;
- return 0;
- }
- i = j + 1;
- }
- }
-
- host[0] = 0;
- if (gethostname(host,sizeof host) == -1) return -1;
- host[(sizeof host) - 1] = 0;
- i = str_chr(host,'.');
- if (host[i]) {
- if (!stralloc_copys(rules,"?:")) return -1;
- if (!stralloc_cats(rules,host + i)) return -1;
- if (!stralloc_0(rules)) return -1;
- }
- if (!stralloc_cats(rules,"*.:")) return -1;
- if (!stralloc_0(rules)) return -1;
-
- return 0;
-}
-
-static int ok = 0;
-static unsigned int uses;
-static struct taia deadline;
-static stralloc rules = {0}; /* defined if ok */
-
-int dns_resolvconfrewrite(stralloc *out)
-{
- struct taia now;
-
- taia_now(&now);
- if (taia_less(&deadline,&now)) ok = 0;
- if (!uses) ok = 0;
-
- if (!ok) {
- if (init(&rules) == -1) return -1;
- taia_uint(&deadline,600);
- taia_add(&deadline,&now,&deadline);
- uses = 10000;
- ok = 1;
- }
-
- --uses;
- if (!stralloc_copy(out,&rules)) return -1;
- return 0;
-}
diff -rNU3 ucspi-tcp-0.88/dns_resolve.c ucspi-tcp-0.88.ipv6/dns_resolve.c
--- ucspi-tcp-0.88/dns_resolve.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_resolve.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,29 +0,0 @@
-#include "iopause.h"
-#include "taia.h"
-#include "byte.h"
-#include "dns.h"
-
-struct dns_transmit dns_resolve_tx = {0};
-
-int dns_resolve(char *q,char qtype[2])
-{
- struct taia stamp;
- struct taia deadline;
- char servers[64];
- iopause_fd x[1];
- int r;
-
- if (dns_resolvconfip(servers) == -1) return -1;
- if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,"\0\0\0\0") == -1) return -1;
-
- for (;;) {
- taia_now(&stamp);
- taia_uint(&deadline,120);
- taia_add(&deadline,&deadline,&stamp);
- dns_transmit_io(&dns_resolve_tx,x,&deadline);
- iopause(x,1,&deadline,&stamp);
- r = dns_transmit_get(&dns_resolve_tx,x,&stamp);
- if (r == -1) return -1;
- if (r == 1) return 0;
- }
-}
diff -rNU3 ucspi-tcp-0.88/dns_sortip.c ucspi-tcp-0.88.ipv6/dns_sortip.c
--- ucspi-tcp-0.88/dns_sortip.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_sortip.c 2012-02-17 12:55:08.000000000 +0100
@@ -1,20 +0,0 @@
-#include "byte.h"
-#include "dns.h"
-
-/* XXX: sort servers by configurable notion of closeness? */
-/* XXX: pay attention to competence of each server? */
-
-void dns_sortip(char *s,unsigned int n)
-{
- unsigned int i;
- char tmp[4];
-
- n >>= 2;
- while (n > 1) {
- i = dns_random(n);
- --n;
- byte_copy(tmp,4,s + (i << 2));
- byte_copy(s + (i << 2),4,s + (n << 2));
- byte_copy(s + (n << 2),4,tmp);
- }
-}
diff -rNU3 ucspi-tcp-0.88/dns_transmit.c ucspi-tcp-0.88.ipv6/dns_transmit.c
--- ucspi-tcp-0.88/dns_transmit.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_transmit.c 2012-02-17 12:55:13.000000000 +0100
@@ -1,366 +0,0 @@
-#include "socket.h"
-#include "alloc.h"
-#include "error.h"
-#include "byte.h"
-#include <unistd.h>
-#include "uint16.h"
-#include "dns.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-
-static int serverwantstcp(char *buf,unsigned int len)
-{
- char out[12];
-
- if (!dns_packet_copy(buf,len,0,out,12)) return 1;
- if (out[2] & 2) return 1;
- return 0;
-}
-
-static int serverfailed(char *buf,unsigned int len)
-{
- char out[12];
- unsigned int rcode;
-
- if (!dns_packet_copy(buf,len,0,out,12)) return 1;
- rcode = out[3];
- rcode &= 15;
- if (rcode && (rcode != 3)) { errno = error_again; return 1; }
- return 0;
-}
-
-static int irrelevant(struct dns_transmit *d,char *buf,unsigned int len)
-{
- char out[12];
- char *dn;
- unsigned int pos;
-
- pos = dns_packet_copy(buf,len,0,out,12); if (!pos) return 1;
- if (byte_diff(out,2,d->query + 2)) return 1;
- if (out[4] != 0) return 1;
- if (out[5] != 1) return 1;
-
- dn = 0;
- pos = dns_packet_getname(buf,len,pos,&dn); if (!pos) return 1;
- if (!dns_domain_equal(dn,d->query + 14)) { alloc_free(dn); return 1; }
- alloc_free(dn);
-
- pos = dns_packet_copy(buf,len,pos,out,4); if (!pos) return 1;
- if (byte_diff(out,2,d->qtype)) return 1;
- if (byte_diff(out + 2,2,DNS_C_IN)) return 1;
-
- return 0;
-}
-
-static void packetfree(struct dns_transmit *d)
-{
- if (!d->packet) return;
- alloc_free(d->packet);
- d->packet = 0;
-}
-
-static void queryfree(struct dns_transmit *d)
-{
- if (!d->query) return;
- alloc_free(d->query);
- d->query = 0;
-}
-
-static void socketfree(struct dns_transmit *d)
-{
- if (!d->s1) return;
- close(d->s1 - 1);
- d->s1 = 0;
-}
-
-void dns_transmit_free(struct dns_transmit *d)
-{
- queryfree(d);
- socketfree(d);
- packetfree(d);
-}
-
-static int randombind(struct dns_transmit *d)
-{
- int j;
-
- for (j = 0;j < 10;++j)
- if (socket_bind4(d->s1 - 1,d->localip,1025 + dns_random(64510)) == 0)
- return 0;
- if (socket_bind4(d->s1 - 1,d->localip,0) == 0)
- return 0;
- return -1;
-}
-
-static const int timeouts[4] = { 1, 3, 11, 45 };
-
-static int thisudp(struct dns_transmit *d)
-{
- char *ip;
-
- socketfree(d);
-
- while (d->udploop < 4) {
- for (;d->curserver < 16;++d->curserver) {
- ip = d->servers + 4 * d->curserver;
- if (byte_diff(ip,4,"\0\0\0\0")) {
- d->query[2] = dns_random(256);
- d->query[3] = dns_random(256);
-
- d->s1 = 1 + socket_udp();
- if (!d->s1) { dns_transmit_free(d); return -1; }
- if (randombind(d) == -1) { dns_transmit_free(d); return -1; }
-
- if (socket_connect4(d->s1 - 1,ip,53) == 0)
- if (send(d->s1 - 1,d->query + 2,d->querylen - 2,0) == d->querylen - 2) {
- struct taia now;
- taia_now(&now);
- taia_uint(&d->deadline,timeouts[d->udploop]);
- taia_add(&d->deadline,&d->deadline,&now);
- d->tcpstate = 0;
- return 0;
- }
-
- socketfree(d);
- }
- }
-
- ++d->udploop;
- d->curserver = 0;
- }
-
- dns_transmit_free(d); return -1;
-}
-
-static int firstudp(struct dns_transmit *d)
-{
- d->curserver = 0;
- return thisudp(d);
-}
-
-static int nextudp(struct dns_transmit *d)
-{
- ++d->curserver;
- return thisudp(d);
-}
-
-static int thistcp(struct dns_transmit *d)
-{
- struct taia now;
- char *ip;
-
- socketfree(d);
- packetfree(d);
-
- for (;d->curserver < 16;++d->curserver) {
- ip = d->servers + 4 * d->curserver;
- if (byte_diff(ip,4,"\0\0\0\0")) {
- d->query[2] = dns_random(256);
- d->query[3] = dns_random(256);
-
- d->s1 = 1 + socket_tcp();
- if (!d->s1) { dns_transmit_free(d); return -1; }
- if (randombind(d) == -1) { dns_transmit_free(d); return -1; }
-
- taia_now(&now);
- taia_uint(&d->deadline,10);
- taia_add(&d->deadline,&d->deadline,&now);
- if (socket_connect4(d->s1 - 1,ip,53) == 0) {
- d->tcpstate = 2;
- return 0;
- }
- if ((errno == error_inprogress) || (errno == error_wouldblock)) {
- d->tcpstate = 1;
- return 0;
- }
-
- socketfree(d);
- }
- }
-
- dns_transmit_free(d); return -1;
-}
-
-static int firsttcp(struct dns_transmit *d)
-{
- d->curserver = 0;
- return thistcp(d);
-}
-
-static int nexttcp(struct dns_transmit *d)
-{
- ++d->curserver;
- return thistcp(d);
-}
-
-int dns_transmit_start(struct dns_transmit *d,char servers[64],int flagrecursive,char *q,char qtype[2],char localip[4])
-{
- unsigned int len;
-
- dns_transmit_free(d);
- errno = error_io;
-
- len = dns_domain_length(q);
- d->querylen = len + 18;
- d->query = alloc(d->querylen);
- if (!d->query) return -1;
-
- uint16_pack_big(d->query,len + 16);
- byte_copy(d->query + 2,12,flagrecursive ? "\0\0\1\0\0\1\0\0\0\0\0\0" : "\0\0\0\0\0\1\0\0\0\0\0\0gcc-bug-workaround");
- byte_copy(d->query + 14,len,q);
- byte_copy(d->query + 14 + len,2,qtype);
- byte_copy(d->query + 16 + len,2,DNS_C_IN);
-
- byte_copy(d->qtype,2,qtype);
- d->servers = servers;
- byte_copy(d->localip,4,localip);
-
- d->udploop = flagrecursive ? 1 : 0;
-
- if (len + 16 > 512) return firsttcp(d);
- return firstudp(d);
-}
-
-void dns_transmit_io(struct dns_transmit *d,iopause_fd *x,struct taia *deadline)
-{
- x->fd = d->s1 - 1;
-
- switch(d->tcpstate) {
- case 0: case 3: case 4: case 5:
- x->events = IOPAUSE_READ;
- break;
- case 1: case 2:
- x->events = IOPAUSE_WRITE;
- break;
- }
-
- if (taia_less(&d->deadline,deadline))
- *deadline = d->deadline;
-}
-
-int dns_transmit_get(struct dns_transmit *d,iopause_fd *x,struct taia *when)
-{
- char udpbuf[513];
- unsigned char ch;
- int r;
- int fd;
-
- errno = error_io;
- fd = d->s1 - 1;
-
- if (!x->revents) {
- if (taia_less(when,&d->deadline)) return 0;
- errno = error_timeout;
- if (d->tcpstate == 0) return nextudp(d);
- return nexttcp(d);
- }
-
- if (d->tcpstate == 0) {
-/*
-have attempted to send UDP query to each server udploop times
-have sent query to curserver on UDP socket s
-*/
- r = recv(fd,udpbuf,sizeof udpbuf,0);
- if (r <= 0) {
- if (d->udploop == 2) return 0;
- return nextudp(d);
- }
- if (r + 1 > sizeof udpbuf) return 0;
-
- if (irrelevant(d,udpbuf,r)) return 0;
- if (serverwantstcp(udpbuf,r)) return firsttcp(d);
- if (serverfailed(udpbuf,r)) {
- if (d->udploop == 2) return 0;
- return nextudp(d);
- }
- socketfree(d);
-
- d->packetlen = r;
- d->packet = alloc(d->packetlen);
- if (!d->packet) { dns_transmit_free(d); return -1; }
- byte_copy(d->packet,d->packetlen,udpbuf);
- queryfree(d);
- return 1;
- }
-
- if (d->tcpstate == 1) {
-/*
-have sent connection attempt to curserver on TCP socket s
-pos not defined
-*/
- if (!socket_connected(fd)) return nexttcp(d);
- d->pos = 0;
- d->tcpstate = 2;
- return 0;
- }
-
- if (d->tcpstate == 2) {
-/*
-have connection to curserver on TCP socket s
-have sent pos bytes of query
-*/
- r = write(fd,d->query + d->pos,d->querylen - d->pos);
- if (r <= 0) return nexttcp(d);
- d->pos += r;
- if (d->pos == d->querylen) {
- struct taia now;
- taia_now(&now);
- taia_uint(&d->deadline,10);
- taia_add(&d->deadline,&d->deadline,&now);
- d->tcpstate = 3;
- }
- return 0;
- }
-
- if (d->tcpstate == 3) {
-/*
-have sent entire query to curserver on TCP socket s
-pos not defined
-*/
- r = read(fd,&ch,1);
- if (r <= 0) return nexttcp(d);
- d->packetlen = ch;
- d->tcpstate = 4;
- return 0;
- }
-
- if (d->tcpstate == 4) {
-/*
-have sent entire query to curserver on TCP socket s
-pos not defined
-have received one byte of packet length into packetlen
-*/
- r = read(fd,&ch,1);
- if (r <= 0) return nexttcp(d);
- d->packetlen <<= 8;
- d->packetlen += ch;
- d->tcpstate = 5;
- d->pos = 0;
- d->packet = alloc(d->packetlen);
- if (!d->packet) { dns_transmit_free(d); return -1; }
- return 0;
- }
-
- if (d->tcpstate == 5) {
-/*
-have sent entire query to curserver on TCP socket s
-have received entire packet length into packetlen
-packet is allocated
-have received pos bytes of packet
-*/
- r = read(fd,d->packet + d->pos,d->packetlen - d->pos);
- if (r <= 0) return nexttcp(d);
- d->pos += r;
- if (d->pos < d->packetlen) return 0;
-
- socketfree(d);
- if (irrelevant(d,d->packet,d->packetlen)) return nexttcp(d);
- if (serverwantstcp(d->packet,d->packetlen)) return nexttcp(d);
- if (serverfailed(d->packet,d->packetlen)) return nexttcp(d);
-
- queryfree(d);
- return 1;
- }
-
- return 0;
-}
diff -rNU3 ucspi-tcp-0.88/dns_txt.c ucspi-tcp-0.88.ipv6/dns_txt.c
--- ucspi-tcp-0.88/dns_txt.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/dns_txt.c 2012-02-17 14:42:23.000000000 +0100
@@ -1,8 +1,13 @@
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include "stralloc.h"
#include "uint16.h"
#include "byte.h"
#include "dns.h"
+#define MAX_ANSWER 1024
+
int dns_txt_packet(stralloc *out,char *buf,unsigned int len)
{
unsigned int pos;
@@ -46,14 +51,25 @@
return 0;
}
-static char *q = 0;
-
int dns_txt(stralloc *out,stralloc *fqdn)
{
- if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1;
- if (dns_resolve(q,DNS_T_TXT) == -1) return -1;
- if (dns_txt_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1;
- dns_transmit_free(&dns_resolve_tx);
- dns_domain_free(&q);
- return 0;
+static int was_initialized = 0;
+static stralloc tmp = {0};
+int l;
+
+ if (!was_initialized) {
+ if (res_init())
+ return -1;
+ was_initialized = 1;
+ }
+
+ if (!stralloc_ready(&tmp, MAX_ANSWER))
+ return -1;
+ if (!stralloc_catb(fqdn, "", 1))
+ return -1;
+
+ l = res_query(fqdn->s, C_IN, T_TXT, tmp.s, tmp.a);
+ if (l < 0)
+ return -1;
+ return dns_txt_packet(out, tmp.s, l);
}
diff -rNU3 ucspi-tcp-0.88/ip4.h ucspi-tcp-0.88.ipv6/ip4.h
--- ucspi-tcp-0.88/ip4.h 2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/ip4.h 2012-02-17 13:47:34.000000000 +0100
@@ -1,9 +1,19 @@
#ifndef IP4_H
#define IP4_H
-extern unsigned int ip4_scan(char *,char *);
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
extern unsigned int ip4_fmt(char *,char *);
#define IP4_FMT 20
+typedef union {
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+} socket_address;
+
+extern const char V6_MAPPED_PREFIX[];
+
#endif
diff -rNU3 ucspi-tcp-0.88/ip4_scan.c ucspi-tcp-0.88.ipv6/ip4_scan.c
--- ucspi-tcp-0.88/ip4_scan.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/ip4_scan.c 2012-02-17 13:47:38.000000000 +0100
@@ -1,19 +1,4 @@
#include "scan.h"
#include "ip4.h"
-unsigned int ip4_scan(char *s,char ip[4])
-{
- unsigned int i;
- unsigned int len;
- unsigned long u;
-
- len = 0;
- i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i;
- if (*s != '.') return 0; ++s; ++len;
- i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i;
- if (*s != '.') return 0; ++s; ++len;
- i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i;
- if (*s != '.') return 0; ++s; ++len;
- i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i;
- return len;
-}
+const char V6_MAPPED_PREFIX[] = "\0\0\0\0\0\0\0\0\0\0\377\377";
diff -rNU3 ucspi-tcp-0.88/Makefile ucspi-tcp-0.88.ipv6/Makefile
--- ucspi-tcp-0.88/Makefile 2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/Makefile 2012-02-17 14:08:30.000000000 +0100
@@ -179,87 +179,19 @@
./compile delcr.c
dns.a: \
-makelib dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o \
-dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o \
-dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o
- ./makelib dns.a dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o \
- dns_ipq.o dns_name.o dns_nd.o dns_packet.o dns_random.o \
- dns_rcip.o dns_rcrw.o dns_resolve.o dns_sortip.o \
- dns_transmit.o dns_txt.o
-
-dns_dfd.o: \
-compile dns_dfd.c error.h alloc.h byte.h dns.h stralloc.h gen_alloc.h \
-iopause.h taia.h tai.h uint64.h taia.h
- ./compile dns_dfd.c
+makelib dns_domain.o dns_packet.o dns_txt.o
+ ./makelib dns.a dns_domain.o dns_packet.o dns_txt.o
dns_domain.o: \
compile dns_domain.c error.h alloc.h case.h byte.h dns.h stralloc.h \
gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h
./compile dns_domain.c
-dns_dtda.o: \
-compile dns_dtda.c stralloc.h gen_alloc.h dns.h stralloc.h iopause.h \
-taia.h tai.h uint64.h taia.h
- ./compile dns_dtda.c
-
-dns_ip.o: \
-compile dns_ip.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \
-stralloc.h iopause.h taia.h tai.h uint64.h taia.h
- ./compile dns_ip.c
-
-dns_ipq.o: \
-compile dns_ipq.c stralloc.h gen_alloc.h case.h byte.h str.h dns.h \
-stralloc.h iopause.h taia.h tai.h uint64.h taia.h
- ./compile dns_ipq.c
-
-dns_name.o: \
-compile dns_name.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \
-stralloc.h iopause.h taia.h tai.h uint64.h taia.h
- ./compile dns_name.c
-
-dns_nd.o: \
-compile dns_nd.c byte.h fmt.h dns.h stralloc.h gen_alloc.h iopause.h \
-taia.h tai.h uint64.h taia.h
- ./compile dns_nd.c
-
dns_packet.o: \
compile dns_packet.c error.h dns.h stralloc.h gen_alloc.h iopause.h \
taia.h tai.h uint64.h taia.h
./compile dns_packet.c
-dns_random.o: \
-compile dns_random.c dns.h stralloc.h gen_alloc.h iopause.h taia.h \
-tai.h uint64.h taia.h taia.h uint32.h
- ./compile dns_random.c
-
-dns_rcip.o: \
-compile dns_rcip.c taia.h tai.h uint64.h openreadclose.h stralloc.h \
-gen_alloc.h byte.h ip4.h env.h dns.h stralloc.h iopause.h taia.h \
-taia.h
- ./compile dns_rcip.c
-
-dns_rcrw.o: \
-compile dns_rcrw.c taia.h tai.h uint64.h env.h byte.h str.h \
-openreadclose.h stralloc.h gen_alloc.h dns.h stralloc.h iopause.h \
-taia.h taia.h
- ./compile dns_rcrw.c
-
-dns_resolve.o: \
-compile dns_resolve.c iopause.h taia.h tai.h uint64.h taia.h byte.h \
-dns.h stralloc.h gen_alloc.h iopause.h taia.h
- ./compile dns_resolve.c
-
-dns_sortip.o: \
-compile dns_sortip.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \
-taia.h tai.h uint64.h taia.h
- ./compile dns_sortip.c
-
-dns_transmit.o: \
-compile dns_transmit.c socket.h uint16.h alloc.h error.h byte.h \
-readwrite.h uint16.h dns.h stralloc.h gen_alloc.h iopause.h taia.h \
-tai.h uint64.h taia.h
- ./compile dns_transmit.c
-
dns_txt.o: \
compile dns_txt.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \
stralloc.h iopause.h taia.h tai.h uint64.h taia.h
@@ -472,7 +404,7 @@
rblsmtpd: \
load rblsmtpd.o commands.o dns.a time.a unix.a byte.a socket.lib
./load rblsmtpd commands.o dns.a time.a unix.a byte.a \
- `cat socket.lib`
+ `cat socket.lib` -lresolv
rblsmtpd.o: \
compile rblsmtpd.c byte.h str.h scan.h fmt.h env.h exit.h sig.h \
@@ -556,14 +488,6 @@
&& echo -lsocket -lnsl || exit 0 ) > socket.lib
rm -f trylsock.o trylsock
-socket_accept.o: \
-compile socket_accept.c byte.h socket.h uint16.h
- ./compile socket_accept.c
-
-socket_bind.o: \
-compile socket_bind.c byte.h socket.h uint16.h
- ./compile socket_bind.c
-
socket_conn.o: \
compile socket_conn.c readwrite.h byte.h socket.h uint16.h
./compile socket_conn.c
@@ -576,26 +500,10 @@
compile socket_listen.c socket.h uint16.h
./compile socket_listen.c
-socket_local.o: \
-compile socket_local.c byte.h socket.h uint16.h
- ./compile socket_local.c
-
socket_opts.o: \
compile socket_opts.c socket.h uint16.h
./compile socket_opts.c
-socket_remote.o: \
-compile socket_remote.c byte.h socket.h uint16.h
- ./compile socket_remote.c
-
-socket_tcp.o: \
-compile socket_tcp.c ndelay.h socket.h uint16.h
- ./compile socket_tcp.c
-
-socket_udp.o: \
-compile socket_udp.c ndelay.h socket.h uint16.h
- ./compile socket_udp.c
-
str_chr.o: \
compile str_chr.c str.h
./compile str_chr.c
@@ -710,9 +618,9 @@
chmod 755 tcpcat
tcpclient: \
-load tcpclient.o remoteinfo.o timeoutconn.o dns.a time.a unix.a \
+load tcpclient.o remoteinfo.o timeoutconn.o time.a unix.a \
byte.a socket.lib
- ./load tcpclient remoteinfo.o timeoutconn.o dns.a time.a \
+ ./load tcpclient remoteinfo.o timeoutconn.o time.a \
unix.a byte.a `cat socket.lib`
tcpclient.o: \
@@ -742,10 +650,10 @@
./compile tcprulescheck.c
tcpserver: \
-load tcpserver.o rules.o remoteinfo.o timeoutconn.o cdb.a dns.a \
+load tcpserver.o rules.o remoteinfo.o timeoutconn.o cdb.a \
time.a unix.a byte.a socket.lib
./load tcpserver rules.o remoteinfo.o timeoutconn.o cdb.a \
- dns.a time.a unix.a byte.a `cat socket.lib`
+ time.a unix.a byte.a `cat socket.lib`
tcpserver.o: \
compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \
@@ -801,9 +709,9 @@
fd_copy.o fd_move.o getln.o getln2.o ndelay_off.o ndelay_on.o \
open_read.o open_trunc.o open_write.o openreadclose.o pathexec_env.o \
pathexec_run.o prot.o readclose.o seek_set.o sgetopt.o sig.o \
-sig_block.o sig_catch.o sig_pause.o socket_accept.o socket_bind.o \
-socket_conn.o socket_delay.o socket_listen.o socket_local.o \
-socket_opts.o socket_remote.o socket_tcp.o socket_udp.o \
+sig_block.o sig_catch.o sig_pause.o \
+socket_conn.o socket_delay.o socket_listen.o \
+socket_opts.o \
stralloc_cat.o stralloc_catb.o stralloc_cats.o stralloc_copy.o \
stralloc_eady.o stralloc_opyb.o stralloc_opys.o stralloc_pend.o \
strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o wait_pid.o
@@ -813,10 +721,10 @@
getln.o getln2.o ndelay_off.o ndelay_on.o open_read.o \
open_trunc.o open_write.o openreadclose.o pathexec_env.o \
pathexec_run.o prot.o readclose.o seek_set.o sgetopt.o \
- sig.o sig_block.o sig_catch.o sig_pause.o socket_accept.o \
- socket_bind.o socket_conn.o socket_delay.o socket_listen.o \
- socket_local.o socket_opts.o socket_remote.o socket_tcp.o \
- socket_udp.o stralloc_cat.o stralloc_catb.o stralloc_cats.o \
+ sig.o sig_block.o sig_catch.o sig_pause.o \
+ socket_conn.o socket_delay.o socket_listen.o \
+ socket_opts.o \
+ stralloc_cat.o stralloc_catb.o stralloc_cats.o \
stralloc_copy.o stralloc_eady.o stralloc_opyb.o \
stralloc_opys.o stralloc_pend.o strerr_die.o strerr_sys.o \
subgetopt.o wait_nohang.o wait_pid.o
diff -rNU3 ucspi-tcp-0.88/rblsmtpd.c ucspi-tcp-0.88.ipv6/rblsmtpd.c
--- ucspi-tcp-0.88/rblsmtpd.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/rblsmtpd.c 2012-02-17 21:33:50.000000000 +0100
@@ -13,9 +13,14 @@
#include "commands.h"
#include "pathexec.h"
#include "dns.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
#define FATAL "rblsmtpd: fatal: "
+static char *HEX = "0123456789abcdef";
+
void nomem(void)
{
strerr_die2x(111,FATAL,"out of memory");
@@ -31,7 +36,7 @@
void ip_init(void)
{
unsigned int i;
- unsigned int j;
+ unsigned int j, haveDot=0, haveColon=0;
ip_env = env_get("TCPREMOTEIP");
if (!ip_env) ip_env = "";
@@ -40,12 +45,33 @@
i = str_len(ip_env);
while (i) {
- for (j = i;j > 0;--j) if (ip_env[j - 1] == '.') break;
+ for (j = i;j > 0;--j) {
+ if (ip_env[j - 1] == '.') { haveDot++; break; }
+ if (ip_env[j - 1] == ':') { haveColon = 1; break; }
+ }
if (!stralloc_catb(&ip_reverse,ip_env + j,i - j)) nomem();
if (!stralloc_cats(&ip_reverse,".")) nomem();
- if (!j) break;
+ if (!j || haveColon) break;
i = j - 1;
}
+ if (!haveDot && ip_reverse.len) { /* assume IPv6 */
+ struct addrinfo *res, hints={0};
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (!getaddrinfo(ip_env, NULL, &hints, &res) && res != NULL) {
+ if (res->ai_family == AF_INET6) {
+ if (!stralloc_copys(&ip_reverse,"")) nomem();
+ for (j = 16; j > 0; j--) {
+ unsigned int tmp = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr[j-1];
+ if (!stralloc_catb(&ip_reverse, HEX + (tmp & 0xf), 1)) nomem();
+ if (!stralloc_catb(&ip_reverse, ".", 1)) nomem();
+ if (!stralloc_catb(&ip_reverse, HEX + ((tmp >> 4) & 0xf), 1)) nomem();
+ if (!stralloc_catb(&ip_reverse, ".", 1)) nomem();
+ }
+ }
+ freeaddrinfo(res);
+ }
+ }
}
unsigned long timeout = 60;
@@ -61,6 +87,7 @@
void rbl(char *base)
{
+ struct addrinfo *res;
int i;
char *altreply = 0;
if (decision) return;
@@ -72,7 +99,8 @@
}
if (!stralloc_cats(&tmp,base)) nomem();
if (altreply) {
- if (dns_ip4(&text,&tmp) == -1) {
+ if (!stralloc_catb(&tmp, "", 1)) nomem();
+ if (getaddrinfo(tmp.s, NULL, NULL, &res)) {
flagmustnotbounce = 1;
if (flagfailclosed) {
if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem();
@@ -80,7 +108,8 @@
}
return;
}
- if (text.len) {
+ if (res) {
+ freeaddrinfo(res);
if(!stralloc_copys(&text, "")) nomem();
while(*altreply) {
char *x;
@@ -119,17 +148,21 @@
void antirbl(char *base)
{
+ struct addrinfo *res;
if (decision) return;
if (!stralloc_copy(&tmp,&ip_reverse)) nomem();
if (!stralloc_cats(&tmp,base)) nomem();
- if (dns_ip4(&text,&tmp) == -1) {
+ if (!stralloc_catb(&tmp, "", 1)) nomem();
+ if (getaddrinfo(tmp.s, NULL, NULL, &res)) {
flagmustnotbounce = 1;
if (!flagfailclosed)
decision = 1;
return;
}
- if (text.len)
+ if (res) {
+ freeaddrinfo(res);
decision = 1;
+ }
}
char strnum[FMT_ULONG];
@@ -139,18 +172,18 @@
char outspace[1]; buffer out = BUFFER_INIT(write,1,outspace,sizeof outspace);
void reject() { buffer_putflush(&out,message.s,message.len); }
-void accept() { buffer_putsflush(&out,"250 rblsmtpd.local\r\n"); }
+void smtp_accept() { buffer_putsflush(&out,"250 rblsmtpd.local\r\n"); }
void greet() { buffer_putsflush(&out,"220 rblsmtpd.local\r\n"); }
void quit() { buffer_putsflush(&out,"221 rblsmtpd.local\r\n"); _exit(0); }
void drop() { _exit(0); }
struct commands smtpcommands[] = {
{ "quit", quit, 0 }
-, { "helo", accept, 0 }
-, { "ehlo", accept, 0 }
-, { "mail", accept, 0 }
-, { "rset", accept, 0 }
-, { "noop", accept, 0 }
+, { "helo", smtp_accept, 0 }
+, { "ehlo", smtp_accept, 0 }
+, { "mail", smtp_accept, 0 }
+, { "rset", smtp_accept, 0 }
+, { "noop", smtp_accept, 0 }
, { 0, reject, 0 }
} ;
diff -rNU3 ucspi-tcp-0.88/remoteinfo.c ucspi-tcp-0.88.ipv6/remoteinfo.c
--- ucspi-tcp-0.88/remoteinfo.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/remoteinfo.c 2012-02-06 16:53:41.000000000 +0100
@@ -1,3 +1,4 @@
+#include "byte.h"
#include "fmt.h"
#include "buffer.h"
#include "socket.h"
@@ -6,6 +7,7 @@
#include "timeoutconn.h"
#include "remoteinfo.h"
#include <unistd.h>
+#include "ip4.h"
static struct taia now;
static struct taia deadline;
@@ -46,21 +48,34 @@
return read(fd,buf,len);
}
-static int doit(stralloc *out,int s,char ipremote[4],uint16 portremote,char iplocal[4],uint16 portlocal,unsigned int timeout)
+static int doit(stralloc *out,int s,socket_address *remote,socket_address *local,unsigned int timeout)
{
buffer b;
char bspace[128];
char strnum[FMT_ULONG];
int numcolons;
char ch;
+ socket_address iplocal, ipremote;
- if (socket_bind4(s,iplocal,0) == -1) return -1;
- if (timeoutconn(s,ipremote,113,timeout) == -1) return -1;
+ byte_copy(&iplocal,sizeof(iplocal),local);
+ if (iplocal.sa6.sin6_family == AF_INET6) {
+ iplocal.sa6.sin6_port = 0;
+ } else {
+ iplocal.sa4.sin_port = 0;
+ }
+ if (bind(s,(struct sockaddr *) &iplocal.sa4,iplocal.sa4.sin_family == AF_INET ? sizeof(iplocal.sa4) : sizeof(iplocal.sa6)) == -1) return -1;
+ byte_copy(&ipremote,sizeof(ipremote),remote);
+ if (ipremote.sa6.sin6_family == AF_INET6) {
+ ipremote.sa6.sin6_port = htons(113);
+ } else {
+ ipremote.sa4.sin_port = htons(113);
+ }
+ if (timeoutconn(s,&ipremote,timeout) == -1) return -1;
buffer_init(&b,mywrite,s,bspace,sizeof bspace);
- buffer_put(&b,strnum,fmt_ulong(strnum,portremote));
+ buffer_put(&b,strnum,fmt_ulong(strnum,ntohs(remote->sa4.sin_family == AF_INET ? remote->sa4.sin_port : remote->sa6.sin6_port)));
buffer_put(&b," , ",3);
- buffer_put(&b,strnum,fmt_ulong(strnum,portlocal));
+ buffer_put(&b,strnum,fmt_ulong(strnum,ntohs(local->sa4.sin_family == AF_INET ? local->sa4.sin_port : local->sa6.sin6_port)));
buffer_put(&b,"\r\n",2);
if (buffer_flush(&b) == -1) return -1;
@@ -80,7 +95,7 @@
}
}
-int remoteinfo(stralloc *out,char ipremote[4],uint16 portremote,char iplocal[4],uint16 portlocal,unsigned int timeout)
+int remoteinfo(stralloc *out,socket_address *remote,socket_address *local,unsigned int timeout)
{
int s;
int r;
@@ -91,9 +106,9 @@
taia_uint(&deadline,timeout);
taia_add(&deadline,&now,&deadline);
- s = socket_tcp();
+ s = socket(remote->sa4.sin_family, SOCK_STREAM, 0);
if (s == -1) return -1;
- r = doit(out,s,ipremote,portremote,iplocal,portlocal,timeout);
+ r = doit(out,s,remote,local,timeout);
close(s);
return r;
}
diff -rNU3 ucspi-tcp-0.88/remoteinfo.h ucspi-tcp-0.88.ipv6/remoteinfo.h
--- ucspi-tcp-0.88/remoteinfo.h 2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/remoteinfo.h 2012-02-06 11:49:08.000000000 +0100
@@ -3,7 +3,8 @@
#include "stralloc.h"
#include "uint16.h"
+#include "ip4.h"
-extern int remoteinfo(stralloc *,char *,uint16,char *,uint16,unsigned int);
+extern int remoteinfo(stralloc *,socket_address *,socket_address *,unsigned int);
#endif
diff -rNU3 ucspi-tcp-0.88/rts.exp ucspi-tcp-0.88.ipv6/rts.exp
--- ucspi-tcp-0.88/rts.exp 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/rts.exp 2012-02-18 22:02:53.000000000 +0100
@@ -1,8 +1,8 @@
--- tcpclient prints usage message without enough arguments
-tcpclient: usage: tcpclient [ -hHrRdDqQv ] [ -i localip ] [ -p localport ] [ -T timeoutconn ] [ -l localname ] [ -t timeoutinfo ] host port program
+tcpclient: usage: tcpclient [ -hHrRdDqQv46 ] [ -i localip ] [ -p localport ] [ -T timeoutconn ] [ -l localname ] [ -t timeoutinfo ] host port program
100
--- tcpclient prints error message with unknown port name
-tcpclient: fatal: unable to figure out port number for nonexistentport
+tcpclient: fatal: no IP address for 127.0.0.1/nonexistentport
111
--- tcpclient prints error message when connection fails
tcpclient: unable to connect to 127.0.0.1 port 16: connection refused
@@ -18,14 +18,20 @@
--- tcpclient understands bracketed IP address
tcpclient: unable to connect to 127.0.0.1 port 16: connection refused
111
+--- tcpclient understands unbracketed IP6 address
+tcpclient: unable to connect to ::1 port 16: connection refused
+111
+--- tcpclient understands bracketed IP6 address
+tcpclient: unable to connect to ::1 port 16: connection refused
+111
--- tcpclient prints error message with unknown host name
-tcpclient: fatal: no IP address for nonexistent.local.
+tcpclient: fatal: no IP address for nonexistent.local./016
111
--- tcpclient prints error message with unresolvable host name
-tcpclient: fatal: temporarily unable to figure out IP address for thislabelistoolongbecausednshasalimitof63charactersinasinglelabel.: protocol error
+tcpclient: fatal: no IP address for thislabelistoolongbecausednshasalimitof63charactersinasinglelabel./016
111
--- tcpserver prints usage message without enough arguments
-tcpserver: usage: tcpserver [ -1UXpPhHrRoOdDqQv ] [ -c limit ] [ -x rules.cdb ] [ -B banner ] [ -g gid ] [ -u uid ] [ -b backlog ] [ -l localname ] [ -t timeout ] host port program
+tcpserver: usage: tcpserver [ -1UXpPhHrRoOdDqQv46 ] [ -c limit ] [ -x rules.cdb ] [ -B banner ] [ -g gid ] [ -u uid ] [ -b backlog ] [ -l localname ] [ -t timeout ] host port program
100
--- tcpserver -u 1 attempts to set uid to 1
tcpserver: fatal: unable to set uid: permission denied
@@ -40,13 +46,13 @@
tcpserver: fatal: unable to set gid: permission denied
111
--- tcpserver prints error message with unknown port name
-tcpserver: fatal: unable to figure out port number for nonexistentport
+tcpserver: fatal: no IP address for ''/nonexistentport
111
--- tcpserver prints error message with unknown host name
-tcpserver: fatal: no IP address for nonexistent.local.
+tcpserver: fatal: no IP address for nonexistent.local./016
111
--- tcpserver prints error message with unresolvable host name
-tcpserver: fatal: temporarily unable to figure out IP address for thislabelistoolongbecausednshasalimitof63charactersinasinglelabel.: protocol error
+tcpserver: fatal: no IP address for thislabelistoolongbecausednshasalimitof63charactersinasinglelabel./016
111
--- tcpserver prints error message with non-local host name
tcpserver: fatal: unable to bind: address not available
@@ -61,6 +67,16 @@
TCPREMOTEPORT=50017
TCPREMOTEINFO=unset
0
+--- tcpserver sets basic environment variables
+bannerPROTO=TCP
+TCPLOCALHOST=Local
+TCPLOCALIP=::1
+TCPLOCALPORT=50015
+TCPREMOTEHOST=localhost
+TCPREMOTEIP=::1
+TCPREMOTEPORT=50017
+TCPREMOTEINFO=unset
+0
--- tcpclient recognizes -D, -i, -r, -h, -t
bannerPROTO=TCP
TCPLOCALHOST=Local
@@ -71,6 +87,16 @@
TCPREMOTEPORT=50018
TCPREMOTEINFO=unset
0
+--- tcpclient recognizes -D, -i, -r, -h, -t
+bannerPROTO=TCP
+TCPLOCALHOST=Local
+TCPLOCALIP=::1
+TCPLOCALPORT=50015
+TCPREMOTEHOST=localhost
+TCPREMOTEIP=::1
+TCPREMOTEPORT=50018
+TCPREMOTEINFO=unset
+0
--- tcpclient sets basic environment variables
PROTO=TCP
TCPLOCALHOST=Local
@@ -81,6 +107,16 @@
TCPREMOTEPORT=50016
TCPREMOTEINFO=unset
0
+--- tcpclient sets basic environment variables
+PROTO=TCP
+TCPLOCALHOST=Local
+TCPLOCALIP=::1
+TCPLOCALPORT=50019
+TCPREMOTEHOST=unset
+TCPREMOTEIP=::1
+TCPREMOTEPORT=50015
+TCPREMOTEINFO=unset
+0
--- tcpclient looks up host names properly
PROTO=TCP
TCPLOCALHOST=localhost
@@ -91,10 +127,36 @@
TCPREMOTEPORT=50016
TCPREMOTEINFO=unset
0
+--- tcpclient looks up host names properly
+PROTO=TCP
+TCPLOCALHOST=localhost
+TCPLOCALIP=::1
+TCPLOCALPORT=50020
+TCPREMOTEHOST=localhost
+TCPREMOTEIP=::1
+TCPREMOTEPORT=50015
+TCPREMOTEINFO=unset
+0
--- tcpclient -v works
tcpclient: connected to 127.0.0.1 port 50016
ok
0
+--- tcpclient -v works
+tcpclient: connected to ::1 port 50015
+ok
+0
+--- tcpclient -4 works
+tcpclient: unable to connect to 127.0.0.1 port 50015: connection refused
+111
+tcpclient: connected to 127.0.0.1 port 50016
+ok
+0
+--- tcpclient -6 works
+tcpclient: connected to ::1 port 50015
+ok
+0
+tcpclient: unable to connect to ::1 port 50016: connection refused
+111
--- tcpserver prints error message with used port
tcpserver: fatal: unable to bind: address already used
111
@@ -107,6 +169,15 @@
TCPREMOTEIP=127.0.0.1
TCPREMOTEINFO=unset
0
+--- tcpcat works
+bannerPROTO=TCP
+TCPLOCALHOST=Local
+TCPLOCALIP=::1
+TCPLOCALPORT=50015
+TCPREMOTEHOST=localhost
+TCPREMOTEIP=::1
+TCPREMOTEINFO=unset
+0
--- mconnect works
bannerPROTO=TCP
TCPLOCALHOST=Local
@@ -116,6 +187,15 @@
TCPREMOTEIP=127.0.0.1
TCPREMOTEINFO=unset
0
+--- mconnect works
+bannerPROTO=TCP
+TCPLOCALHOST=Local
+TCPLOCALIP=::1
+TCPLOCALPORT=50015
+TCPREMOTEHOST=localhost
+TCPREMOTEIP=::1
+TCPREMOTEINFO=unset
+0
--- tcprules prints usage message without enough arguments
tcprules: usage: tcprules rules.cdb rules.tmp
100
@@ -208,6 +288,24 @@
deny connection
rule =.abuser.edu:
deny connection
+--- tcprules handles IPv6
+0
+rule 20014ba0fff100bfc0011337d00ddead:
+set environment variable which=full
+allow connection
+rule 20014ba0fff100bfc001:
+set environment variable which=part
+allow connection
+rule 00000000000000000000000000000001:
+set environment variable which=full
+allow connection
+rule 0:
+deny connection
+rule 0:
+deny connection
+rule :
+set environment variable which=anybody
+allow connection
--- tcprulescheck searches for rules in the proper order
0
rule xyz@86.75.30.9:
@@ -354,12 +452,24 @@
--- rblsmtpd does not find 127.0.0.1 on the RBL
ok
0
+--- rblsmtpd does not find ::ffff:127.0.0.1 on the RBL
+ok
+0
+--- rblsmtpd does not find ::1 on the RBL
+ok
+0
--- rblsmtpd finds 127.0.0.2 on the RBL
rblsmtpd: 127.0.0.2 pid x: 451 http://www.spamhaus.org/SBL/sbl.lasso?query=SBL233http://www.spamhaus.org/query/bl?ip=127.0.0.2
220 rblsmtpd.local^M
451 http://www.spamhaus.org/SBL/sbl.lasso?query=SBL233http://www.spamhaus.org/query/bl?ip=127.0.0.2^M
221 rblsmtpd.local^M
0
+--- rblsmtpd finds ::ffff:127.0.0.2 on the RBL
+rblsmtpd: ::ffff:127.0.0.2 pid x: 451 http://www.spamhaus.org/SBL/sbl.lasso?query=SBL233http://www.spamhaus.org/query/bl?ip=127.0.0.2
+220 rblsmtpd.local^M
+451 http://www.spamhaus.org/SBL/sbl.lasso?query=SBL233http://www.spamhaus.org/query/bl?ip=127.0.0.2^M
+221 rblsmtpd.local^M
+0
--- rblsmtpd -b uses a permanent error code
rblsmtpd: 127.0.0.2 pid x: 553 http://www.spamhaus.org/SBL/sbl.lasso?query=SBL233http://www.spamhaus.org/query/bl?ip=127.0.0.2
220 rblsmtpd.local^M
@@ -433,3 +543,51 @@
tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x
tcpserver: end x status 0
tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from 127.0.0.1
+tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+--- tcpserver -1v prints proper messages
+50015
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
+tcpserver: status: 1/2
+tcpserver: pid x from ::1
+tcpserver: ok x Local:??1:50015 localhost:??1::x
+tcpserver: end x status 0
+tcpserver: status: 0/2
diff -rNU3 ucspi-tcp-0.88/rts.tests ucspi-tcp-0.88.ipv6/rts.tests
--- ucspi-tcp-0.88/rts.tests 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/rts.tests 2012-02-18 21:56:13.000000000 +0100
@@ -37,6 +37,16 @@
supervise 50016 >log 2>&1 &
+mkdir 50015
+echo '#!/bin/sh
+exec tcpserver \
+-c 2 -Bbanner -vo -D -1 -Xx rules.cdb -Rt5 -hp -l Local -b 2 \
+::1 50015 ../print
+' > 50015/run
+chmod 755 50015/run
+
+supervise 50015 >log2 2>&1 &
+
echo '--- tcpclient prints usage message without enough arguments'
tcpclient 0 0; echo $?
@@ -58,6 +68,12 @@
echo '--- tcpclient understands bracketed IP address'
tcpclient '[127.000.000.001]' 016 echo wrong; echo $?
+echo '--- tcpclient understands unbracketed IP6 address'
+tcpclient '::1' 016 echo wrong; echo $?
+
+echo '--- tcpclient understands bracketed IP6 address'
+tcpclient '[::1]' 016 echo wrong; echo $?
+
echo '--- tcpclient prints error message with unknown host name'
tcpclient nonexistent.local. 016 echo wrong; echo $?
@@ -96,38 +112,87 @@
echo $?
sleep 1
+echo '--- tcpserver sets basic environment variables'
+tcpclient -p 50017 -R -H -T 10 -l Local ::1 50015 sh -c 'cat <&6'
+echo $?
+sleep 1
+
echo '--- tcpclient recognizes -D, -i, -r, -h, -t'
tcpclient -Di 127.0.0.1 -p 50018 -hrt1 -l Local \
127.0.0.1 50016 sh -c 'cat <&6'
echo $?
sleep 1
+echo '--- tcpclient recognizes -D, -i, -r, -h, -t'
+tcpclient -Di ::1 -p 50018 -hrt1 -l Local \
+::1 50015 sh -c 'cat <&6'
+echo $?
+sleep 1
+
echo '--- tcpclient sets basic environment variables'
tcpclient -p 50019 -R -H -l Local 0 50016 ./print
echo $?
sleep 1
+echo '--- tcpclient sets basic environment variables'
+tcpclient -p 50019 -R -H -l Local ::1 50015 ./print
+echo $?
+sleep 1
+
echo '--- tcpclient looks up host names properly'
tcpclient -p 50020 -R 0 50016 ./print
echo $?
sleep 1
+echo '--- tcpclient looks up host names properly'
+tcpclient -p 50020 -R ::1 50015 ./print
+echo $?
+sleep 1
+
echo '--- tcpclient -v works'
tcpclient -v -R -H -l Local 0 50016 sh -c 'echo ok; sleep 1'
echo $?
sleep 1
+echo '--- tcpclient -v works'
+tcpclient -v -R -H -l Local ::1 50015 sh -c 'echo ok; sleep 1'
+echo $?
+sleep 1
+
+echo '--- tcpclient -4 works'
+tcpclient -v -R -H -l Local -4 localhost 50015 sh -c 'echo wrong; sleep 1'
+echo $?
+tcpclient -v -R -H -l Local -4 localhost 50016 sh -c 'echo ok; sleep 1'
+echo $?
+sleep 1
+
+echo '--- tcpclient -6 works'
+tcpclient -v -R -H -l Local -6 localhost 50015 sh -c 'echo ok; sleep 1'
+echo $?
+tcpclient -v -R -H -l Local -6 localhost 50016 sh -c 'echo wrong; sleep 1'
+echo $?
+sleep 1
+
echo '--- tcpserver prints error message with used port'
tcpserver -R -H -l Local 127.0.0.1 50016 echo wrong
echo $?
echo '--- tcpcat works'
-tcpcat 0 50016 | grep -v TCPREMOTEPORT
+tcpcat 127.0.0.1 50016 | grep -v TCPREMOTEPORT
echo $?
sleep 1
+echo '--- tcpcat works'
+tcpcat ::1 50015 | grep -v TCPREMOTEPORT
+echo $?
+sleep 1
+
+echo '--- mconnect works'
+mconnect 127.0.0.1 50016 </dev/null | grep -v TCPREMOTEPORT
+echo $?
+
echo '--- mconnect works'
-mconnect 0 50016 </dev/null | grep -v TCPREMOTEPORT
+mconnect ::1 50015 </dev/null | grep -v TCPREMOTEPORT
echo $?
echo '--- tcprules prints usage message without enough arguments'
@@ -191,6 +256,19 @@
env TCPREMOTEIP=1.2.3.4 TCPREMOTEHOST=x.abuser.edu tcprulescheck test.cdb
env TCPREMOTEIP=1.2.3.4 TCPREMOTEHOST=x.y.abuser.edu tcprulescheck test.cdb
+echo '--- tcprules handles IPv6'
+echo '20014ba0fff100bfc0011337d00ddead:allow,which=/full/
+20014ba0fff100bfc001:allow,which=/part/
+00000000000000000000000000000001:allow,which=/full/
+0:deny
+:allow,which=/anybody/' | tcprules test.cdb test.tmp; echo $?
+env TCPREMOTEIP=2001:4ba0:fff1:bf:c001:1337:d00d:dead tcprulescheck test.cdb
+env TCPREMOTEIP=2001:4ba0:fff1:bf:c001::1 tcprulescheck test.cdb
+env TCPREMOTEIP=::1 tcprulescheck test.cdb
+env TCPREMOTEIP=::2 tcprulescheck test.cdb
+env TCPREMOTEIP=1::1 tcprulescheck test.cdb
+env TCPREMOTEIP=fe80::212:37ff:fe8c:c886 tcprulescheck test.cdb
+
echo '--- tcprulescheck searches for rules in the proper order'
echo 'xyz@86.75.30.9:allow,which=/first/
xyz@=one.two.three:allow,which=/second/
@@ -298,11 +376,26 @@
| ( TCPREMOTEIP=127.0.0.1 rblsmtpd -r zen.spamhaus.org echo ok 2>&1; echo $? ) \
| sed 's/pid [0-9]*/pid x/'
+echo '--- rblsmtpd does not find ::ffff:127.0.0.1 on the RBL'
+( echo help; echo quit ) \
+| ( TCPREMOTEIP=::ffff:127.0.0.1 rblsmtpd -r zen.spamhaus.org echo ok 2>&1; echo $? ) \
+| sed 's/pid [0-9]*/pid x/'
+
+echo '--- rblsmtpd does not find ::1 on the RBL'
+( echo help; echo quit ) \
+| ( TCPREMOTEIP=::1 rblsmtpd -r zen.spamhaus.org echo ok 2>&1; echo $? ) \
+| sed 's/pid [0-9]*/pid x/'
+
echo '--- rblsmtpd finds 127.0.0.2 on the RBL'
( echo help; echo quit ) \
| ( TCPREMOTEIP=127.0.0.2 rblsmtpd -r zen.spamhaus.org echo whoops 2>&1; echo $? ) \
| sed 's/pid [0-9]*/pid x/'
+echo '--- rblsmtpd finds ::ffff:127.0.0.2 on the RBL'
+( echo help; echo quit ) \
+| ( TCPREMOTEIP=::ffff:127.0.0.2 rblsmtpd -r zen.spamhaus.org echo whoops 2>&1; echo $? ) \
+| sed 's/pid [0-9]*/pid x/'
+
echo '--- rblsmtpd -b uses a permanent error code'
( echo help; echo quit ) \
| ( TCPREMOTEIP=127.0.0.2 rblsmtpd -b -r zen.spamhaus.org echo whoops 2>&1; echo $? ) \
@@ -345,10 +438,14 @@
svc -dx 50016
+svc -dx 50015
wait
echo '--- tcpserver -1v prints proper messages'
sed -e 's/::.*/::x/' -e 's/ [0-9]* / x /' < log
+echo '--- tcpserver -1v prints proper messages'
+sed -e 's/::[02-9]$/::x/;s/::[0-9][0-9][0-9]*$/::x/' -e 's/ [0-9]* / x /' < log2
+
exit 0
diff -rNU3 ucspi-tcp-0.88/rules.c ucspi-tcp-0.88.ipv6/rules.c
--- ucspi-tcp-0.88/rules.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/rules.c 2012-02-17 16:58:00.000000000 +0100
@@ -1,13 +1,17 @@
#include "alloc.h"
+#include "byte.h"
#include "stralloc.h"
#include "open.h"
#include "cdb.h"
#include "rules.h"
stralloc rules_name = {0};
+static stralloc remote = {0};
static struct cdb c;
+static const char HEX[] = "0123456789abcdef";
+
static int dorule(void (*callback)(char *,unsigned int))
{
char *data;
@@ -31,14 +35,29 @@
return 1;
}
-static int doit(void (*callback)(char *,unsigned int),char *ip,char *host,char *info)
+static int doit(void (*callback)(char *,unsigned int),socket_address *ip,char *host,char *info)
{
- int r;
+ int r, v6=0;
+ if (ip->sa4.sin_family == AF_INET) {
+ if (stralloc_ready(&remote, IP4_FMT) == -1) return -1;
+ remote.len = ip4_fmt(remote.s, (char*) &ip->sa4.sin_addr.s_addr);
+ } else if (byte_equal(ip->sa6.sin6_addr.s6_addr, 12, V6_MAPPED_PREFIX)) {
+ if (stralloc_ready(&remote, IP4_FMT) == -1) return -1;
+ remote.len = ip4_fmt(remote.s, ip->sa6.sin6_addr.s6_addr+12);
+ } else {
+ v6 = 1;
+ if (stralloc_ready(&remote, 16*2 + 1) == -1) return -1;
+ stralloc_copys(&remote, "");
+ for (r = 0; r < 16; r++) {
+ remote.s[remote.len++] = HEX[(ip->sa6.sin6_addr.s6_addr[r] >> 4) & 0xf];
+ remote.s[remote.len++] = HEX[ip->sa6.sin6_addr.s6_addr[r] & 0xf];
+ }
+ }
if (info) {
if (!stralloc_copys(&rules_name,info)) return -1;
if (!stralloc_cats(&rules_name,"@")) return -1;
- if (!stralloc_cats(&rules_name,ip)) return -1;
+ if (!stralloc_cat(&rules_name,&remote)) return -1;
r = dorule(callback);
if (r) return r;
@@ -51,7 +70,7 @@
}
}
- if (!stralloc_copys(&rules_name,ip)) return -1;
+ if (!stralloc_copy(&rules_name, &remote)) return -1;
r = dorule(callback);
if (r) return r;
@@ -62,9 +81,9 @@
if (r) return r;
}
- if (!stralloc_copys(&rules_name,ip)) return -1;
+ if (!stralloc_copy(&rules_name, &remote)) return -1;
while (rules_name.len > 0) {
- if (ip[rules_name.len - 1] == '.') {
+ if (v6 || rules_name.s[rules_name.len - 1] == '.') {
r = dorule(callback);
if (r) return r;
}
@@ -90,7 +109,7 @@
return dorule(callback);
}
-int rules(void (*callback)(char *,unsigned int),int fd,char *ip,char *host,char *info)
+int rules(void (*callback)(char *,unsigned int),int fd,socket_address *ip,char *host,char *info)
{
int r;
cdb_init(&c,fd);
diff -rNU3 ucspi-tcp-0.88/rules.h ucspi-tcp-0.88.ipv6/rules.h
--- ucspi-tcp-0.88/rules.h 2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/rules.h 2012-02-06 14:40:35.000000000 +0100
@@ -2,8 +2,9 @@
#define RULES_H
#include "stralloc.h"
+#include "ip4.h"
extern stralloc rules_name;
-extern int rules(void (*)(char *,unsigned int),int,char *,char *,char *);
+extern int rules(void (*)(char *,unsigned int),int,socket_address *,char *,char *);
#endif
diff -rNU3 ucspi-tcp-0.88/socket_accept.c ucspi-tcp-0.88.ipv6/socket_accept.c
--- ucspi-tcp-0.88/socket_accept.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket_accept.c 2012-02-17 10:58:34.000000000 +0100
@@ -1,21 +0,0 @@
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "byte.h"
-#include "socket.h"
-
-int socket_accept4(int s,char ip[4],uint16 *port)
-{
- struct sockaddr_in sa;
- int dummy = sizeof sa;
- int fd;
-
- fd = accept(s,(struct sockaddr *) &sa,&dummy);
- if (fd == -1) return -1;
-
- byte_copy(ip,4,(char *) &sa.sin_addr);
- uint16_unpack_big((char *) &sa.sin_port,port);
-
- return fd;
-}
diff -rNU3 ucspi-tcp-0.88/socket_bind.c ucspi-tcp-0.88.ipv6/socket_bind.c
--- ucspi-tcp-0.88/socket_bind.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket_bind.c 2012-02-17 13:42:53.000000000 +0100
@@ -1,33 +0,0 @@
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "byte.h"
-#include "socket.h"
-
-int socket_bind4(int s,char ip[4],uint16 port)
-{
- struct sockaddr_in sa;
-
- byte_zero(&sa,sizeof sa);
- sa.sin_family = AF_INET;
- uint16_pack_big((char *) &sa.sin_port,port);
- byte_copy((char *) &sa.sin_addr,4,ip);
-
- return bind(s,(struct sockaddr *) &sa,sizeof sa);
-}
-
-int socket_bind4_reuse(int s,char ip[4],uint16 port)
-{
- int opt = 1;
- setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt);
- return socket_bind4(s,ip,port);
-}
-
-void socket_tryreservein(int s,int size)
-{
- while (size >= 1024) {
- if (setsockopt(s,SOL_SOCKET,SO_RCVBUF,&size,sizeof size) == 0) return;
- size -= (size >> 5);
- }
-}
diff -rNU3 ucspi-tcp-0.88/socket_conn.c ucspi-tcp-0.88.ipv6/socket_conn.c
--- ucspi-tcp-0.88/socket_conn.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket_conn.c 2012-02-17 13:43:15.000000000 +0100
@@ -5,22 +5,11 @@
#include <unistd.h>
#include "byte.h"
#include "socket.h"
-
-int socket_connect4(int s,char ip[4],uint16 port)
-{
- struct sockaddr_in sa;
-
- byte_zero(&sa,sizeof sa);
- sa.sin_family = AF_INET;
- uint16_pack_big((char *) &sa.sin_port,port);
- byte_copy((char *) &sa.sin_addr,4,ip);
-
- return connect(s,(struct sockaddr *) &sa,sizeof sa);
-}
+#include "ip4.h"
int socket_connected(int s)
{
- struct sockaddr_in sa;
+ socket_address sa;
int dummy;
char ch;
diff -rNU3 ucspi-tcp-0.88/socket.h ucspi-tcp-0.88.ipv6/socket.h
--- ucspi-tcp-0.88/socket.h 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket.h 2012-02-17 13:43:41.000000000 +0100
@@ -3,20 +3,7 @@
#include "uint16.h"
-extern int socket_tcp(void);
-extern int socket_udp(void);
-
-extern int socket_connect4(int,char *,uint16);
extern int socket_connected(int);
-extern int socket_bind4(int,char *,uint16);
-extern int socket_bind4_reuse(int,char *,uint16);
extern int socket_listen(int,int);
-extern int socket_accept4(int,char *,uint16 *);
-extern int socket_recv4(int,char *,int,char *,uint16 *);
-extern int socket_send4(int,char *,int,char *,uint16);
-extern int socket_local4(int,char *,uint16 *);
-extern int socket_remote4(int,char *,uint16 *);
-
-extern void socket_tryreservein(int,int);
#endif
diff -rNU3 ucspi-tcp-0.88/socket_local.c ucspi-tcp-0.88.ipv6/socket_local.c
--- ucspi-tcp-0.88/socket_local.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket_local.c 2012-02-17 10:58:44.000000000 +0100
@@ -1,17 +0,0 @@
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "byte.h"
-#include "socket.h"
-
-int socket_local4(int s,char ip[4],uint16 *port)
-{
- struct sockaddr_in sa;
- int dummy = sizeof sa;
-
- if (getsockname(s,(struct sockaddr *) &sa,&dummy) == -1) return -1;
- byte_copy(ip,4,(char *) &sa.sin_addr);
- uint16_unpack_big((char *) &sa.sin_port,port);
- return 0;
-}
diff -rNU3 ucspi-tcp-0.88/socket_remote.c ucspi-tcp-0.88.ipv6/socket_remote.c
--- ucspi-tcp-0.88/socket_remote.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket_remote.c 2012-02-17 10:58:39.000000000 +0100
@@ -1,17 +0,0 @@
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "byte.h"
-#include "socket.h"
-
-int socket_remote4(int s,char ip[4],uint16 *port)
-{
- struct sockaddr_in sa;
- int dummy = sizeof sa;
-
- if (getpeername(s,(struct sockaddr *) &sa,&dummy) == -1) return -1;
- byte_copy(ip,4,(char *) &sa.sin_addr);
- uint16_unpack_big((char *) &sa.sin_port,port);
- return 0;
-}
diff -rNU3 ucspi-tcp-0.88/socket_tcp.c ucspi-tcp-0.88.ipv6/socket_tcp.c
--- ucspi-tcp-0.88/socket_tcp.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket_tcp.c 2012-02-17 13:43:27.000000000 +0100
@@ -1,17 +0,0 @@
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "ndelay.h"
-#include "socket.h"
-#include <unistd.h>
-
-int socket_tcp(void)
-{
- int s;
-
- s = socket(AF_INET,SOCK_STREAM,0);
- if (s == -1) return -1;
- if (ndelay_on(s) == -1) { close(s); return -1; }
- return s;
-}
diff -rNU3 ucspi-tcp-0.88/socket_udp.c ucspi-tcp-0.88.ipv6/socket_udp.c
--- ucspi-tcp-0.88/socket_udp.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/socket_udp.c 2012-02-17 13:43:30.000000000 +0100
@@ -1,17 +0,0 @@
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include "ndelay.h"
-#include "socket.h"
-#include <unistd.h>
-
-int socket_udp(void)
-{
- int s;
-
- s = socket(AF_INET,SOCK_DGRAM,0);
- if (s == -1) return -1;
- if (ndelay_on(s) == -1) { close(s); return -1; }
- return s;
-}
diff -rNU3 ucspi-tcp-0.88/strerr_die.c ucspi-tcp-0.88.ipv6/strerr_die.c
--- ucspi-tcp-0.88/strerr_die.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/strerr_die.c 2012-02-06 16:50:16.000000000 +0100
@@ -2,7 +2,7 @@
#include "exit.h"
#include "strerr.h"
-void strerr_warn(char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se)
+void strerr_warn(const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,struct strerr *se)
{
strerr_sysinit();
@@ -24,7 +24,7 @@
buffer_flush(buffer_2);
}
-void strerr_die(int e,char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se)
+void strerr_die(int e,const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,struct strerr *se)
{
strerr_warn(x1,x2,x3,x4,x5,x6,se);
_exit(e);
diff -rNU3 ucspi-tcp-0.88/strerr.h ucspi-tcp-0.88.ipv6/strerr.h
--- ucspi-tcp-0.88/strerr.h 2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/strerr.h 2012-02-06 16:50:27.000000000 +0100
@@ -12,8 +12,8 @@
extern void strerr_sysinit(void);
extern char *strerr(struct strerr *);
-extern void strerr_warn(char *,char *,char *,char *,char *,char *,struct strerr *);
-extern void strerr_die(int,char *,char *,char *,char *,char *,char *,struct strerr *);
+extern void strerr_warn(const char *,const char *,const char *,const char *,const char *,const char *,struct strerr *);
+extern void strerr_die(int,const char *,const char *,const char *,const char *,const char *,const char *,struct strerr *);
#define STRERR(r,se,a) \
{ se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; }
diff -rNU3 ucspi-tcp-0.88/tcpclient.c ucspi-tcp-0.88.ipv6/tcpclient.c
--- ucspi-tcp-0.88/tcpclient.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/tcpclient.c 2012-02-17 16:36:51.000000000 +0100
@@ -19,7 +19,8 @@
#include "pathexec.h"
#include "timeoutconn.h"
#include "remoteinfo.h"
-#include "dns.h"
+#include "ip4.h"
+#include "byte.h"
#define FATAL "tcpclient: fatal: "
#define CONNECT "tcpclient: unable to connect to "
@@ -31,7 +32,7 @@
void usage(void)
{
strerr_die1x(100,"tcpclient: usage: tcpclient \
-[ -hHrRdDqQv ] \
+[ -hHrRdDqQv46 ] \
[ -i localip ] \
[ -p localport ] \
[ -T timeoutconn ] \
@@ -47,19 +48,14 @@
unsigned long itimeout = 26;
unsigned long ctimeout[2] = { 2, 58 };
-char iplocal[4] = { 0,0,0,0 };
-uint16 portlocal = 0;
char *forcelocal = 0;
-char ipremote[4];
-uint16 portremote;
+socket_address local, remote;
char *hostname;
-static stralloc addresses;
static stralloc moreaddresses;
static stralloc tmp;
-static stralloc fqdn;
char strnum[FMT_ULONG];
char ipstr[IP4_FMT];
@@ -67,20 +65,20 @@
main(int argc,char **argv)
{
- unsigned long u;
int opt;
- char *x;
+ char *x, *portname, *localname = NULL, *portlocal = NULL;
int j;
int s;
int cloop;
-
- dns_random_init(seed);
+ struct addrinfo *to_bind = NULL, *to_connect = NULL, hints = {0}, *bindme;
+ socklen_t addrlen = sizeof(local);
close(6);
close(7);
sig_ignore(sig_pipe);
-
- while ((opt = getopt(argc,argv,"dDvqQhHrRi:p:t:T:l:")) != opteof)
+
+ hints.ai_family = AF_UNSPEC;
+ while ((opt = getopt(argc,argv,"dDvqQhHrRi:p:t:T:l:46")) != opteof)
switch(opt) {
case 'd': flagdelay = 1; break;
case 'D': flagdelay = 0; break;
@@ -97,8 +96,10 @@
if (optarg[j] == '+') ++j;
scan_ulong(optarg + j,&ctimeout[1]);
break;
- case 'i': if (!ip4_scan(optarg,iplocal)) usage(); break;
- case 'p': scan_ulong(optarg,&u); portlocal = u; break;
+ case 'i': localname = optarg; break;
+ case 'p': portlocal = optarg; break;
+ case '4': hints.ai_family = AF_INET; break;
+ case '6': hints.ai_family = AF_INET6; break;
default: usage();
}
argv += optind;
@@ -110,54 +111,70 @@
if (!hostname) usage();
if (str_equal(hostname,"")) hostname = "127.0.0.1";
if (str_equal(hostname,"0")) hostname = "127.0.0.1";
-
- x = *++argv;
- if (!x) usage();
- if (!x[scan_ulong(x,&u)])
- portremote = u;
- else {
- struct servent *se;
- se = getservbyname(x,"tcp");
- if (!se)
- strerr_die3x(111,FATAL,"unable to figure out port number for ",x);
- portremote = ntohs(se->s_port);
- /* i continue to be amazed at the stupidity of the s_port interface */
+ j = strlen(hostname);
+ if (*hostname == '[' && hostname[j-1] == ']') {
+ hostname[j-1] = 0;
+ hostname++;
}
+ portname = *++argv;
+ if (!portname) usage();
+
if (!*++argv) usage();
- if (!stralloc_copys(&tmp,hostname)) nomem();
- if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1)
- strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": ");
- if (addresses.len < 4)
- strerr_die3x(111,FATAL,"no IP address for ",hostname);
+ hints.ai_socktype = SOCK_STREAM;
+ if (hints.ai_family == AF_UNSPEC) {
+ hints.ai_flags |= AI_ADDRCONFIG | AI_V4MAPPED;
+ }
+ if (localname || portlocal) {
+ errno = getaddrinfo(localname, portlocal, &hints, &to_bind);
+ if (errno == EAI_NODATA || !to_bind)
+ strerr_die5x(111,FATAL,"no IP address for ",localname?localname:"''","/",portlocal?portlocal:"0");
+ if (errno)
+ strerr_die5x(111,FATAL,"temporarily unable to figure out IP address for ",localname,": ",gai_strerror(errno));
+ }
+
+ errno = getaddrinfo(hostname, portname, &hints, &to_connect);
+ if (errno == EAI_NODATA || !to_connect)
+ strerr_die5x(111,FATAL,"no IP address for ",hostname,"/",portname);
+ if (errno)
+ strerr_die5x(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": ",gai_strerror(errno));
- if (addresses.len == 4) {
+ if (!to_connect->ai_next) {
ctimeout[0] += ctimeout[1];
ctimeout[1] = 0;
}
+ if (!stralloc_copys(&moreaddresses,"")) nomem();
for (cloop = 0;cloop < 2;++cloop) {
- if (!stralloc_copys(&moreaddresses,"")) nomem();
- for (j = 0;j + 4 <= addresses.len;j += 4) {
- s = socket_tcp();
+ for (j=0, hints.ai_next = to_connect; hints.ai_next; hints.ai_next = hints.ai_next->ai_next, j++) {
+ bindme = to_bind;
+ while (bindme && bindme->ai_family != hints.ai_next->ai_family)
+ bindme = bindme->ai_next;
+ if (!bindme && to_bind) { continue; }
+ if (cloop && !moreaddresses.s[j]) { continue; }
+ s = socket(hints.ai_next->ai_family, hints.ai_next->ai_socktype | SOCK_NONBLOCK,
+ hints.ai_next->ai_protocol);
if (s == -1)
strerr_die2sys(111,FATAL,"unable to create socket: ");
- if (socket_bind4(s,iplocal,portlocal) == -1)
+ if (bindme && bind(s, bindme->ai_addr, bindme->ai_addrlen) == -1)
strerr_die2sys(111,FATAL,"unable to bind socket: ");
- if (timeoutconn(s,addresses.s + j,portremote,ctimeout[cloop]) == 0)
+ byte_copy(&remote, hints.ai_next->ai_addrlen, hints.ai_next->ai_addr);
+ if (timeoutconn(s, &remote, ctimeout[cloop]) == 0)
goto CONNECTED;
close(s);
if (!cloop && ctimeout[1] && (errno == error_timeout)) {
- if (!stralloc_catb(&moreaddresses,addresses.s + j,4)) nomem();
+ if (!stralloc_catb(&moreaddresses, "\001", 1)) nomem();
}
else {
- strnum[fmt_ulong(strnum,portremote)] = 0;
- ipstr[ip4_fmt(ipstr,addresses.s + j)] = 0;
+ if (!stralloc_catb(&moreaddresses, "", 1)) nomem();
+ if (getnameinfo(hints.ai_next->ai_addr, hints.ai_next->ai_addrlen, ipstr, sizeof(ipstr),
+ strnum, sizeof(strnum), NI_NUMERICHOST|NI_NUMERICSERV)) {
+ strerr_die2sys(111, FATAL, "unable to get local host + port: ");
+ }
strerr_warn5(CONNECT,ipstr," port ",strnum,": ",&strerr_sys);
}
}
- if (!stralloc_copy(&addresses,&moreaddresses)) nomem();
}
_exit(111);
@@ -171,43 +188,52 @@
if (!pathexec_env("PROTO","TCP")) nomem();
- if (socket_local4(s,iplocal,&portlocal) == -1)
+ if (getsockname(s,(struct sockaddr *) &local, &addrlen))
strerr_die2sys(111,FATAL,"unable to get local address: ");
- strnum[fmt_ulong(strnum,portlocal)] = 0;
+ if (getnameinfo((struct sockaddr *) &local, sizeof(local), ipstr, sizeof(ipstr),
+ strnum, sizeof(strnum), NI_NUMERICHOST|NI_NUMERICSERV)) {
+ strerr_die2sys(111, FATAL, "unable to get local host + port: ");
+ }
+
if (!pathexec_env("TCPLOCALPORT",strnum)) nomem();
- ipstr[ip4_fmt(ipstr,iplocal)] = 0;
if (!pathexec_env("TCPLOCALIP",ipstr)) nomem();
+ if (!stralloc_ready(&tmp, 1024)) nomem();
x = forcelocal;
- if (!x)
- if (dns_name4(&tmp,iplocal) == 0) {
- if (!stralloc_0(&tmp)) nomem();
- x = tmp.s;
- }
+ if (!x) {
+ stralloc_copyb(&tmp, "", 1);
+ if (getnameinfo((struct sockaddr *) &local, sizeof(local), tmp.s,
+ tmp.a, NULL, 0, NI_NAMEREQD) == 0)
+ if (tmp.s[0]) {
+ x = tmp.s;
+ }
+ }
if (!pathexec_env("TCPLOCALHOST",x)) nomem();
- if (socket_remote4(s,ipremote,&portremote) == -1)
+ opt = sizeof(remote);
+ if (getpeername(s, &remote.sa4, &opt))
strerr_die2sys(111,FATAL,"unable to get remote address: ");
- strnum[fmt_ulong(strnum,portremote)] = 0;
+ if (getnameinfo((struct sockaddr *) &remote, sizeof(remote), ipstr, sizeof(ipstr),
+ strnum, sizeof(strnum), NI_NUMERICHOST|NI_NUMERICSERV))
+ strerr_die2sys(111, FATAL, "unable to get remote host + port: ");
if (!pathexec_env("TCPREMOTEPORT",strnum)) nomem();
- ipstr[ip4_fmt(ipstr,ipremote)] = 0;
if (!pathexec_env("TCPREMOTEIP",ipstr)) nomem();
if (verbosity >= 2)
strerr_warn4("tcpclient: connected to ",ipstr," port ",strnum,0);
x = 0;
- if (flagremotehost)
- if (dns_name4(&tmp,ipremote) == 0) {
- if (!stralloc_0(&tmp)) nomem();
- x = tmp.s;
- }
+ if (flagremotehost
+ && getnameinfo((struct sockaddr *) &remote, sizeof(remote), tmp.s,
+ tmp.a, NULL, 0, NI_NAMEREQD) == 0) {
+ x = tmp.s;
+ }
if (!pathexec_env("TCPREMOTEHOST",x)) nomem();
x = 0;
if (flagremoteinfo)
- if (remoteinfo(&tmp,ipremote,portremote,iplocal,portlocal,itimeout) == 0) {
+ if (remoteinfo(&tmp, &remote, &local, itimeout) == 0) {
if (!stralloc_0(&tmp)) nomem();
x = tmp.s;
}
diff -rNU3 ucspi-tcp-0.88/tcprulescheck.c ucspi-tcp-0.88.ipv6/tcprulescheck.c
--- ucspi-tcp-0.88/tcprulescheck.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/tcprulescheck.c 2012-02-17 10:47:00.000000000 +0100
@@ -5,7 +5,9 @@
#include "rules.h"
#include <unistd.h>
#include "open.h"
-
+#include "ip4.h"
+#include <netdb.h>
+#include "error.h"
void found(char *data,unsigned int datalen)
{
@@ -41,6 +43,8 @@
char *ip;
char *info;
char *host;
+ struct addrinfo *sockaddr = NULL, hints = {0};
+ socket_address address;
fnrules = argv[1];
if (!fnrules)
@@ -51,8 +55,14 @@
info = env_get("TCPREMOTEINFO");
host = env_get("TCPREMOTEHOST");
+ if (getaddrinfo(ip, NULL, &hints, &sockaddr) || sockaddr == NULL)
+ strerr_die2x(100,"tcprulescheck: fatal: couldn't parse TCPREMOTEIP: ",
+ gai_strerror(errno));
+ byte_copy(&address, sockaddr->ai_addrlen, sockaddr->ai_addr);
+ freeaddrinfo(sockaddr);
+
fd = open_read(fnrules);
- if ((fd == -1) || (rules(found,fd,ip,host,info) == -1))
+ if ((fd == -1) || (rules(found, fd, &address, host, info) == -1))
strerr_die3sys(111,"tcprulescheck: fatal: unable to read ",fnrules,": ");
buffer_putsflush(buffer_1,"default:\nallow connection\n");
diff -rNU3 ucspi-tcp-0.88/tcpserver.c ucspi-tcp-0.88.ipv6/tcpserver.c
--- ucspi-tcp-0.88/tcpserver.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/tcpserver.c 2012-02-17 16:41:01.000000000 +0100
@@ -4,6 +4,8 @@
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#ifdef NO_GETLOADAVG
@@ -59,26 +61,22 @@
static stralloc tcpremoteinfo;
-uint16 localport;
-char localportstr[FMT_ULONG];
-char localip[4];
-char localipstr[IP4_FMT];
+char localportstr[40];
+char localipstr[48];
static stralloc localhostsa;
char *localhost = 0;
-uint16 remoteport;
-char remoteportstr[FMT_ULONG];
-char remoteip[4];
-char remoteipstr[IP4_FMT];
+char remoteportstr[40];
+char remoteipstr[48];
static stralloc remotehostsa;
char *remotehost = 0;
+static socket_address local, remote;
+
char strnum[FMT_ULONG];
char strnum2[FMT_ULONG];
static stralloc tmp;
-static stralloc fqdn;
-static stralloc addresses;
static stralloc diemsg_buf;
char bspace[16];
@@ -87,7 +87,7 @@
typedef struct
{
- char ip[4];
+ char ip[16];
pid_t pid;
} baby;
@@ -221,10 +221,14 @@
void doit(int t)
{
- int j;
unsigned long curload = 0;
+ socklen_t addrlen = sizeof(local);
- remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0;
+ if (getnameinfo((struct sockaddr *) &remote, sizeof(remote), remoteipstr, sizeof(remoteipstr),
+ remoteportstr, sizeof(remoteportstr),
+ NI_NUMERICHOST|NI_NUMERICSERV)) {
+ strerr_die2sys(111,DROP,"unable to get remote host + port: ");
+ }
if (verbosity >= 2) {
strnum[fmt_ulong(strnum,getpid())] = 0;
@@ -242,44 +247,69 @@
strerr_die2sys(111,DROP,"unable to print banner: ");
}
- if (socket_local4(t,localip,&localport) == -1)
+ if (getsockname(t,(struct sockaddr *) &local, &addrlen))
strerr_die2sys(111,DROP,"unable to get local address: ");
- localipstr[ip4_fmt(localipstr,localip)] = 0;
- remoteportstr[fmt_ulong(remoteportstr,remoteport)] = 0;
+ if (getnameinfo((struct sockaddr *) &local, sizeof(local), localipstr, sizeof(localipstr),
+ localportstr, sizeof(localportstr),
+ NI_NUMERICHOST|NI_NUMERICSERV)) {
+ strerr_die2sys(111,DROP,"unable to get local host + port: ");
+ }
- if (!localhost)
- if (dns_name4(&localhostsa,localip) == 0)
- if (localhostsa.len) {
- if (!stralloc_0(&localhostsa)) drop_nomem();
+ if (!localhost) {
+ if (!stralloc_ready(&localhostsa, 1024)) drop_nomem();
+ stralloc_copyb(&localhostsa, "", 1);
+ if (getnameinfo((struct sockaddr *) &local, sizeof(local), localhostsa.s,
+ localhostsa.a, NULL, 0, NI_NAMEREQD) == 0)
+ if (localhostsa.s[0]) {
localhost = localhostsa.s;
}
+ }
env("PROTO","TCP");
env("TCPLOCALIP",localipstr);
env("TCPLOCALPORT",localportstr);
env("TCPLOCALHOST",localhost);
- if (flagremotehost)
- if (dns_name4(&remotehostsa,remoteip) == 0)
- if (remotehostsa.len) {
- if (flagparanoid)
- if (dns_ip4(&tmp,&remotehostsa) == 0)
- for (j = 0;j + 4 <= tmp.len;j += 4)
- if (byte_equal(remoteip,4,tmp.s + j)) {
+ if (flagremotehost) {
+ if (!stralloc_ready(&remotehostsa, 1024)) drop_nomem();
+ if (getnameinfo((struct sockaddr *) &remote, sizeof(remote),remotehostsa.s,
+ remotehostsa.a, NULL, 0, NI_NAMEREQD) == 0)
+ if (remotehostsa.s[0]) {
+ if (flagparanoid) {
+ struct addrinfo *reverse, hints = {0};
+ hints.ai_family = remote.sa4.sin_family;
+ if (remote.sa6.sin6_family == AF_INET6) {
+ hints.ai_flags = AI_V4MAPPED | AI_ALL;
+ }
+ if (getaddrinfo(remotehostsa.s, NULL, &hints, &reverse) == 0) {
+ hints.ai_next = reverse;
+ while (hints.ai_next) {
+ if (hints.ai_next->ai_family == AF_INET
+ && remote.sa4.sin_family == AF_INET
+ && byte_equal(&remote.sa4.sin_addr, 4, &((struct sockaddr_in*) hints.ai_next->ai_addr)->sin_addr)
+ || hints.ai_next->ai_family == AF_INET6
+ && remote.sa6.sin6_family == AF_INET6
+ && byte_equal(remote.sa6.sin6_addr.s6_addr, 16,
+ &((struct sockaddr_in6*) hints.ai_next->ai_addr)->sin6_addr.s6_addr)) {
flagparanoid = 0;
break;
}
+ hints.ai_next = hints.ai_next->ai_next;
+ }
+ freeaddrinfo(reverse);
+ }
+ }
if (!flagparanoid) {
- if (!stralloc_0(&remotehostsa)) drop_nomem();
remotehost = remotehostsa.s;
}
}
+ }
env("TCPREMOTEIP",remoteipstr);
env("TCPREMOTEPORT",remoteportstr);
env("TCPREMOTEHOST",remotehost);
if (flagremoteinfo) {
- if (remoteinfo(&tcpremoteinfo,remoteip,remoteport,localip,localport,timeout) == -1)
+ if (remoteinfo(&tcpremoteinfo,&remote,&local,timeout) == -1)
flagremoteinfo = 0;
if (!stralloc_0(&tcpremoteinfo)) drop_nomem();
}
@@ -293,7 +323,7 @@
if (!flagallownorules) drop_rules();
}
else {
- if (rules(found,fdrules,remoteipstr,remotehost,flagremoteinfo ? tcpremoteinfo.s : 0) == -1) drop_rules();
+ if (rules(found,fdrules,&remote,remotehost,flagremoteinfo ? tcpremoteinfo.s : 0) == -1) drop_rules();
close(fdrules);
}
}
@@ -306,13 +336,22 @@
if (!flagdeny && (maxconnip != -1 || maxconnc != -1)) {
unsigned long u;
long c1=0, cc=0;
- for (u=0; u < limit; u++) if (child[u].pid != 0) {
- if ((child[u].ip[0] == remoteip[0]) &&
- (child[u].ip[1] == remoteip[1]) &&
- (child[u].ip[2] == remoteip[2]) ) {
+ for (u=0; u < limit; u++) if (child[u].pid != 0) {
+ if (byte_equal(child[u].ip,12,V6_MAPPED_PREFIX)) {
+ if (remote.sa4.sin_family == AF_INET6) {
+ if (byte_equal(child[u].ip+12,3,remote.sa6.sin6_addr.s6_addr+12)) {
+ cc++;
+ if (child[u].ip[15] == remote.sa6.sin6_addr.s6_addr[15]) c1++;
+ }
+ } else if (byte_equal(child[u].ip+12,3,&remote.sa4.sin_addr)) {
cc++;
- if (child[u].ip[3] == remoteip[3]) c1++;
+ if (byte_equal(child[u].ip+12,4,&remote.sa4.sin_addr)) c1++;
}
+ } else if (remote.sa4.sin_family == AF_INET6
+ && byte_equal(child[u].ip,8,remote.sa6.sin6_addr.s6_addr)) {
+ cc++;
+ if (byte_equal(child[u].ip+8,8,remote.sa6.sin6_addr.s6_addr+8)) c1++;
+ }
}
if (maxconnc != -1 && (cc >= maxconnc)) flagdeny = 4;
if (maxconnip != -1 && (c1 >= maxconnip)) flagdeny = 3;
@@ -371,7 +410,7 @@
{
strerr_warn1("\
tcpserver: usage: tcpserver \
-[ -1UXpPhHrRoOdDqQv ] \
+[ -1UXpPhHrRoOdDqQv46 ] \
[ -c limit ] \
[ -x rules.cdb ] \
[ -B banner ] \
@@ -427,14 +466,16 @@
char *hostname;
char *portname;
int opt;
- struct servent *se;
+ struct addrinfo *to_bind = NULL, hints = {0};
char *x;
unsigned long u;
int s;
int t;
pid_t pid;
-
- while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO")) != opteof)
+ socklen_t addrlen = sizeof(local);
+
+ hints.ai_family = AF_UNSPEC;
+ while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO46")) != opteof)
switch(opt) {
case 'b': scan_ulong(optarg,&backlog); break;
case 'c': scan_ulong(optarg,&limit); break;
@@ -460,6 +501,8 @@
case 'g': scan_ulong(optarg,&gid); break;
case '1': flag1 = 1; break;
case 'l': localhost = optarg; break;
+ case '4': hints.ai_family = AF_INET; break;
+ case '6': hints.ai_family = AF_INET6; break;
default: usage();
}
argc -= optind;
@@ -475,19 +518,13 @@
hostname = *argv++;
if (!hostname) usage();
- if (str_equal(hostname,"")) hostname = "0.0.0.0";
- if (str_equal(hostname,"0")) hostname = "0.0.0.0";
+ if (str_equal(hostname,"")) hostname = NULL;
+ if (hostname && str_equal(hostname,"0")) hostname = NULL;
+ if (hostname && str_equal(hostname,"0.0.0.0")) hostname = NULL;
+ if (hostname && str_equal(hostname,"::")) hostname = NULL;
- x = *argv++;
- if (!x) usage();
- if (!x[scan_ulong(x,&u)])
- localport = u;
- else {
- se = getservbyname(x,"tcp");
- if (!se)
- strerr_die3x(111,FATAL,"unable to figure out port number for ",x);
- localport = ntohs(se->s_port);
- }
+ portname = *argv++;
+ if (!portname) usage();
if (!*argv) usage();
@@ -499,21 +536,38 @@
sig_catch(sig_child,sigchld);
sig_catch(sig_term,sigterm);
sig_ignore(sig_pipe);
-
- if (!stralloc_copys(&tmp,hostname))
- strerr_die2x(111,FATAL,"out of memory");
- if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1)
- strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": ");
- if (addresses.len < 4)
- strerr_die3x(111,FATAL,"no IP address for ",hostname);
- byte_copy(localip,4,addresses.s);
-
- s = socket_tcp();
- if (s == -1)
- strerr_die2sys(111,FATAL,"unable to create socket: ");
- if (socket_bind4_reuse(s,localip,localport) == -1)
- strerr_die2sys(111,FATAL,"unable to bind: ");
- if (socket_local4(s,localip,&localport) == -1)
+
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ if (hints.ai_family == AF_UNSPEC) {
+ hints.ai_flags |= AI_ADDRCONFIG | AI_V4MAPPED;
+ }
+ errno = getaddrinfo(hostname, portname, &hints, &to_bind);
+ if (errno == EAI_NODATA || !to_bind)
+ strerr_die5x(111,FATAL,"no IP address for ",hostname?hostname:"''","/",portname);
+ if (errno)
+ strerr_die5x(111,FATAL,"temporarily unable to figure out IP address for ",hostname?hostname:"''",": ",gai_strerror(errno));
+ hints.ai_next = to_bind;
+ do {
+ s = socket(to_bind->ai_family, to_bind->ai_socktype, to_bind->ai_protocol);
+ if (s == -1) {
+ if (!hints.ai_next->ai_next)
+ strerr_die2sys(111,FATAL,"unable to create socket: ");
+ } else if (ndelay_on(s)) {
+ close(s);
+ strerr_die2sys(111,FATAL,"unable to make socket nonblocking: ");
+ } else {
+ opt = 1;
+ setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt);
+ if (bind(s, hints.ai_next->ai_addr, hints.ai_next->ai_addrlen)
+ && !hints.ai_next->ai_next)
+ strerr_die2sys(111,FATAL,"unable to bind: ");
+ }
+ hints.ai_next = hints.ai_next->ai_next;
+ } while (s < 0 && hints.ai_next);
+ freeaddrinfo(to_bind);
+
+ if (getsockname(s, (struct sockaddr *) &local, &addrlen))
strerr_die2sys(111,FATAL,"unable to get local address: ");
if (socket_listen(s,backlog) == -1)
strerr_die2sys(111,FATAL,"unable to listen: ");
@@ -525,7 +577,11 @@
strerr_die2sys(111,FATAL,"unable to set uid: ");
- localportstr[fmt_ulong(localportstr,localport)] = 0;
+ if (getnameinfo((struct sockaddr *) &local, sizeof(local), NULL, 0,
+ localportstr, sizeof(localportstr),
+ NI_NUMERICHOST|NI_NUMERICSERV)) {
+ strerr_die2sys(111,DROP,"unable to get local name: ");
+ }
if (flag1) {
buffer_init(&b,write,1,bspace,sizeof bspace);
buffer_puts(&b,localportstr);
@@ -543,8 +599,9 @@
for (;;) {
while (numchildren >= limit) sig_pause();
+ addrlen = sizeof(remote);
sig_unblock(sig_child);
- t = socket_accept4(s,remoteip,&remoteport);
+ t = accept(s, (struct sockaddr *) &remote, &addrlen);
sig_block(sig_child);
if (t == -1) continue;
@@ -567,7 +624,14 @@
--numchildren; printstatus();
break;
default:
- for (u=0; u < limit; u++) if (child[u].pid == 0) { byte_copy(child[u].ip,4,remoteip); child[u].pid = pid; break; }
+ for (u=0; u < limit; u++) if (child[u].pid == 0) {
+ if (remote.sa4.sin_family == AF_INET) {
+ byte_copy(child[u].ip, 12, V6_MAPPED_PREFIX);
+ byte_copy(child[u].ip+12, 4, (char*) &remote.sa4.sin_addr.s_addr);
+ } else
+ byte_copy(child[u].ip, 16, remote.sa6.sin6_addr.s6_addr);
+ child[u].pid = pid; break;
+ }
if (u == limit) strerr_die1x(111,"tcpserver: ERROR: no empty space for new child?!"); /* never happens */
}
close(t);
Binärdateien ucspi-tcp-0.88/test.cdb and ucspi-tcp-0.88.ipv6/test.cdb sind verschieden.
diff -rNU3 ucspi-tcp-0.88/timeoutconn.c ucspi-tcp-0.88.ipv6/timeoutconn.c
--- ucspi-tcp-0.88/timeoutconn.c 2012-02-20 12:18:21.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/timeoutconn.c 2012-02-06 12:01:14.000000000 +0100
@@ -4,13 +4,13 @@
#include "error.h"
#include "timeoutconn.h"
-int timeoutconn(int s,char ip[4],uint16 port,unsigned int timeout)
+int timeoutconn(int s,socket_address *remote,unsigned int timeout)
{
struct taia now;
struct taia deadline;
iopause_fd x;
- if (socket_connect4(s,ip,port) == -1) {
+ if (connect(s, (struct sockaddr *) &remote->sa4, remote->sa4.sin_family == AF_INET ? sizeof(remote->sa4) : sizeof(remote->sa6)) == -1) {
if ((errno != error_wouldblock) && (errno != error_inprogress)) return -1;
x.fd = s;
x.events = IOPAUSE_WRITE;
diff -rNU3 ucspi-tcp-0.88/timeoutconn.h ucspi-tcp-0.88.ipv6/timeoutconn.h
--- ucspi-tcp-0.88/timeoutconn.h 2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.ipv6/timeoutconn.h 2012-02-06 11:56:23.000000000 +0100
@@ -2,7 +2,8 @@
#define TIMEOUTCONN_H
#include "uint16.h"
+#include "ip4.h"
-extern int timeoutconn(int,char *,uint16,unsigned int);
+extern int timeoutconn(int,socket_address *,unsigned int);
#endif
--- ucspi-tcp-0.88/Makefile.orig 2012-10-04 14:32:31.000000000 +0200
+++ ucspi-tcp-0.88/Makefile 2012-10-04 14:32:33.000000000 +0200
@@ -638,7 +638,7 @@
scan.h str.h ip4.h uint16.h socket.h uint16.h fd.h stralloc.h \
gen_alloc.h buffer.h error.h strerr.h pathexec.h timeoutconn.h \
uint16.h remoteinfo.h stralloc.h uint16.h dns.h stralloc.h iopause.h \
-taia.h tai.h uint64.h taia.h
+taia.h tai.h uint64.h taia.h ndelay.h
./compile tcpclient.c
tcprules: \
--- ucspi-tcp-0.88/tcpclient.c.orig 2012-10-04 14:31:00.000000000 +0200
+++ ucspi-tcp-0.88/tcpclient.c 2012-10-04 14:32:13.000000000 +0200
@@ -21,6 +21,7 @@
#include "remoteinfo.h"
#include "ip4.h"
#include "byte.h"
+#include "ndelay.h"
#define FATAL "tcpclient: fatal: "
#define CONNECT "tcpclient: unable to connect to "
@@ -150,10 +151,14 @@
bindme = bindme->ai_next;
if (!bindme && to_bind) { continue; }
if (cloop && !moreaddresses.s[j]) { continue; }
- s = socket(hints.ai_next->ai_family, hints.ai_next->ai_socktype | SOCK_NONBLOCK,
+ s = socket(hints.ai_next->ai_family, hints.ai_next->ai_socktype,
hints.ai_next->ai_protocol);
if (s == -1)
strerr_die2sys(111,FATAL,"unable to create socket: ");
+ if (ndelay_on(s)) {
+ s = -1;
+ strerr_die2sys(111,FATAL,"unable to create nonblocking socket: ");
+ }
if (bindme && bind(s, bindme->ai_addr, bindme->ai_addrlen) == -1)
strerr_die2sys(111,FATAL,"unable to bind socket: ");
byte_copy(&remote, hints.ai_next->ai_addrlen, hints.ai_next->ai_addr);