File nullmailer-1.05-ipv6.patch of Package nullmailer
diff -rU3 nullmailer-1.05/lib/connect.h nullmailer-1.05-ipv6/lib/connect.h
--- nullmailer-1.05/lib/connect.h 2007-10-08 00:48:27.000000000 +0200
+++ nullmailer-1.05-ipv6/lib/connect.h 2010-12-10 13:55:53.000000000 +0100
@@ -3,6 +3,8 @@
#include "mystring/mystring.h"
-extern int tcpconnect(const mystring& hostname, int port);
+typedef enum { v4_or_v6, v4_only, v6_only } tcpconn_addresstype_t;
+
+extern int tcpconnect(const mystring& hostname, const char* service, const tcpconn_addresstype_t addresstype);
#endif // NULLMAILER_CONNECT__H__
diff -rU3 nullmailer-1.05/lib/tcpconnect.cc nullmailer-1.05-ipv6/lib/tcpconnect.cc
--- nullmailer-1.05/lib/tcpconnect.cc 2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/lib/tcpconnect.cc 2010-12-10 14:07:56.000000000 +0100
@@ -26,43 +26,53 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <unistd.h>
#include "errcodes.h"
#include "connect.h"
-static int sethostbyname(const mystring& hostname, struct sockaddr_in& sa)
+int tcpconnect(const mystring& hostname, const char* service, const tcpconn_addresstype_t addresstype)
{
- struct hostent *he = gethostbyname(hostname.c_str());
- if(!he) {
- switch(h_errno) {
- case HOST_NOT_FOUND: return -ERR_HOST_NOT_FOUND;
- case NO_ADDRESS: return -ERR_NO_ADDRESS;
- case NO_RECOVERY: return -ERR_GHBN_FATAL;
- case TRY_AGAIN: return -ERR_GHBN_TEMP;
+ int family;
+ switch (addresstype) {
+ case v4_only: family = AF_INET; break;
+ case v6_only: family = AF_INET6; break;
+ default: family = AF_INET | AF_INET6;
+ }
+
+ struct addrinfo *ai = NULL,
+ hints = {AI_V4MAPPED | AI_ADDRCONFIG | AI_ALL, family, SOCK_STREAM, 0, 0, NULL, NULL, NULL};
+ if (addresstype == v6_only) { hints.ai_flags &= ~AI_ALL; }
+ int res = getaddrinfo(hostname.c_str(), service, &hints, &ai);
+ if(res != 0) {
+ switch(res) {
+ case EAI_NONAME: return -ERR_HOST_NOT_FOUND;
+ case EAI_FAIL: return -ERR_GHBN_FATAL;
+ case EAI_AGAIN: return -ERR_GHBN_TEMP;
default: return -ERR_GHBN_TEMP;
}
}
- memcpy(&sa.sin_addr, he->h_addr, he->h_length);
- return 0;
-}
-int tcpconnect(const mystring& hostname, int port)
-{
- struct sockaddr_in sa;
- memset(&sa, 0, sizeof(sa));
- int e = sethostbyname(hostname, sa);
- if(e) return e;
- sa.sin_family = AF_INET;
- sa.sin_port = htons(port);
- int s = socket(PF_INET, SOCK_STREAM, 0);
- if(s == -1)
- return -ERR_SOCKET;
- if(connect(s, (sockaddr*)&sa, sizeof(sa)) != 0) {
+ struct addrinfo *trythis = ai;
+ int result = -ERR_HOST_NOT_FOUND;
+ while (trythis) {
+ int s = socket(trythis->ai_addr->sa_family, SOCK_STREAM, 0);
+ if(s == -1) {
+ result = -ERR_SOCKET;
+ break;
+ }
+ if(connect(s, trythis->ai_addr, trythis->ai_addrlen) == 0) {
+ result = s;
+ break;
+ }
switch(errno) {
- case ECONNREFUSED: return -ERR_CONN_REFUSED;
- case ETIMEDOUT: return -ERR_CONN_TIMEDOUT;
- case ENETUNREACH: return -ERR_CONN_UNREACHABLE;
- default: return -ERR_CONN_FAILED;
+ case ECONNREFUSED: result = -ERR_CONN_REFUSED; break;
+ case ETIMEDOUT: result = -ERR_CONN_TIMEDOUT; break;
+ case ENETUNREACH: result = -ERR_CONN_UNREACHABLE; break;
+ default: result = -ERR_CONN_FAILED; break;
}
+ close(s);
+ trythis = trythis->ai_next;
}
- return s;
+ freeaddrinfo(ai);
+ return result;
}
diff -rU3 nullmailer-1.05/protocols/protocol.cc nullmailer-1.05-ipv6/protocols/protocol.cc
--- nullmailer-1.05/protocols/protocol.cc 2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/protocol.cc 2010-12-10 13:44:00.000000000 +0100
@@ -30,12 +30,14 @@
const char* user = 0;
const char* pass = 0;
int auth_method = AUTH_PLAIN;
+int ipv4_only = 0;
+int ipv6_only = 0;
const char* cli_help_suffix = "";
const char* cli_args_usage = "remote-address < mail-file";
const int cli_args_min = 1;
const int cli_args_max = 1;
cli_option cli_options[] = {
- { 'p', "port", cli_option::integer, 0, &port,
+ { 'p', "port", cli_option::string, 0, &port,
"Set the port number on the remote host to connect to", 0 },
{ 0, "user", cli_option::string, 0, &user,
"Set the user name for authentication", 0 },
@@ -43,6 +45,10 @@
"Set the password for authentication", 0 },
{ 0, "auth-login", cli_option::flag, AUTH_LOGIN, &auth_method,
"Use AUTH LOGIN instead of AUTH PLAIN in SMTP", 0 },
+ { '4', "ipv4", cli_option::flag, 1, &ipv4_only,
+ "Try connecting with IPv4 only", 0 },
+ { '6', "ipv6", cli_option::flag, 1, &ipv6_only,
+ "Try connecting with IPv6 only", 0 },
{0, 0, cli_option::flag, 0, 0, 0, 0}
};
@@ -61,9 +67,12 @@
int cli_main(int, char* argv[])
{
const char* remote = argv[0];
+ tcpconn_addresstype_t addresstype = v4_or_v6;
+ if (ipv4_only && !ipv6_only) { addresstype = v4_only; }
+ if (!ipv4_only && ipv6_only) { addresstype = v6_only; }
fdibuf in(0, true);
protocol_prep(&in);
- int fd = tcpconnect(remote, port);
+ int fd = tcpconnect(remote, port, addresstype);
if(fd < 0)
protocol_fail(-fd, "Connect failed");
protocol_send(&in, fd);
diff -rU3 nullmailer-1.05/protocols/protocol.h nullmailer-1.05-ipv6/protocols/protocol.h
--- nullmailer-1.05/protocols/protocol.h 2007-10-08 00:48:27.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/protocol.h 2010-12-10 13:49:41.000000000 +0100
@@ -11,9 +11,11 @@
extern const char* user;
extern const char* pass;
extern int auth_method;
+extern int ipv4_only;
+extern int ipv6_only;
// This must be provided by the protocol, but will be set by the lib.
-extern int port;
+extern const char* port;
extern void protocol_prep(fdibuf* in);
extern void protocol_send(fdibuf* in, int fd);
diff -rU3 nullmailer-1.05/protocols/qmqp.cc nullmailer-1.05-ipv6/protocols/qmqp.cc
--- nullmailer-1.05/protocols/qmqp.cc 2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/qmqp.cc 2010-12-10 13:49:15.000000000 +0100
@@ -30,7 +30,7 @@
#include "netstring.h"
#include "protocol.h"
-int port = 628;
+const char *port = "628";
const char* cli_program = "qmqp";
const char* cli_help_prefix = "Send an emal message via QMQP\n";
diff -rU3 nullmailer-1.05/protocols/smtp.cc nullmailer-1.05-ipv6/protocols/smtp.cc
--- nullmailer-1.05/protocols/smtp.cc 2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/smtp.cc 2010-12-10 13:49:20.000000000 +0100
@@ -30,7 +30,7 @@
#include "mystring/mystring.h"
#include "protocol.h"
-int port = 25;
+const char* port = "25";
const char* cli_program = "smtp";
const char* cli_help_prefix = "Send an email message via SMTP\n";