From: Wietse Venema Date: Mon, 2 Jan 2012 05:00:00 +0000 (-0500) Subject: postfix-2.9-20120102 X-Git-Tag: v2.9.0-RC1~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82a34251f9da30857e51315102563965a6d96565;p=thirdparty%2Fpostfix.git postfix-2.9-20120102 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index af7475222..48365be99 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -17443,3 +17443,12 @@ Apologies for any names omitted. fallback_transport_maps, the local delivery agent did not log the problem before deferring mail, and produced no defer logfile record. Files: local/mailbox.c, local/unknown.c. + +20120102 + + Workaround: degrade gracefully when the network protocols + specified with inet_protocols are unavailable. Files: + global/mail_params.c, global/mynetworks.c, global/own_inet_addr.c + master/master_ent.c, master/master_vars.c, postscreen/postscreen.c, + qmqpd/qmqpd.c, smtp/smtp_connect.c, smtpd/smtpd.c, + util/inet_proto.c. diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index 6a4ee997e..e496ca9fc 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -983,7 +983,6 @@ dict_sqlite.o: db_common.h dict_sqlite.o: dict_sqlite.c dict_sqlite.o: dict_sqlite.h dict_sqlite.o: string_list.h -domain_list.cdebug_peer.o: domain_list.cdebug_peer.c domain_list.o: ../../include/argv.h domain_list.o: ../../include/dict.h domain_list.o: ../../include/match_list.h @@ -1700,6 +1699,7 @@ msg_stats_scan.o: msg_stats.h msg_stats_scan.o: msg_stats_scan.c mynetworks.o: ../../include/argv.h mynetworks.o: ../../include/inet_addr_list.h +mynetworks.o: ../../include/inet_proto.h mynetworks.o: ../../include/mask_addr.h mynetworks.o: ../../include/msg.h mynetworks.o: ../../include/myaddrinfo.h diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index 009beb49b..dff3b72b8 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -510,7 +510,7 @@ void mail_params_init() { static const CONFIG_STR_TABLE first_str_defaults[] = { VAR_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY, &var_syslog_facility, 1, 0, - VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 1, 0, + VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 0, 0, VAR_MULTI_CONF_DIRS, DEF_MULTI_CONF_DIRS, &var_multi_conf_dirs, 0, 0, /* multi_instance_wrapper may have dependencies but not dependents. */ VAR_MULTI_GROUP, DEF_MULTI_GROUP, &var_multi_group, 0, 0, @@ -535,7 +535,7 @@ void mail_params_init() VAR_COMMAND_DIR, DEF_COMMAND_DIR, &var_command_dir, 1, 0, VAR_QUEUE_DIR, DEF_QUEUE_DIR, &var_queue_dir, 1, 0, VAR_PID_DIR, DEF_PID_DIR, &var_pid_dir, 1, 0, - VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 1, 0, + VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 0, 0, VAR_PROXY_INTERFACES, DEF_PROXY_INTERFACES, &var_proxy_interfaces, 0, 0, VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, 1, 0, VAR_DEFAULT_PRIVS, DEF_DEFAULT_PRIVS, &var_default_privs, 1, 0, diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index d48033937..95bf2c2e2 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20111230" +#define MAIL_RELEASE_DATE "20120102" #define MAIL_VERSION_NUMBER "2.9" #ifdef SNAPSHOT diff --git a/postfix/src/global/mynetworks.c b/postfix/src/global/mynetworks.c index f2b9d5c22..93c69676c 100644 --- a/postfix/src/global/mynetworks.c +++ b/postfix/src/global/mynetworks.c @@ -58,6 +58,7 @@ #include #include #include +#include /* Global library. */ @@ -101,6 +102,19 @@ const char *mynetworks(void) BH_TABLE *dup_filter; char **cpp; + /* + * Avoid run-time errors when all network protocols are disabled. We + * can't look up interface information, and we can't convert explicit + * names or addresses. + */ + if (inet_proto_info()->ai_family_list[0] == 0) { + if (msg_verbose) + msg_info("skipping %s setting - " + "all network protocols are disabled", + VAR_MYNETWORKS); + result = vstring_alloc(1); + return (vstring_str(result)); + } mask_style = name_mask("mynetworks mask style", mask_styles, var_mynetworks_style); diff --git a/postfix/src/global/own_inet_addr.c b/postfix/src/global/own_inet_addr.c index 362aaf954..d164a20b2 100644 --- a/postfix/src/global/own_inet_addr.c +++ b/postfix/src/global/own_inet_addr.c @@ -92,6 +92,19 @@ static void own_inet_addr_init(INET_ADDR_LIST *addr_list, inet_addr_list_init(addr_list); inet_addr_list_init(mask_list); + /* + * Avoid run-time errors when all network protocols are disabled. We + * can't look up interface information, and we can't convert explicit + * names or addresses. + */ + if (inet_proto_info()->ai_family_list[0] == 0) { + if (msg_verbose) + msg_info("skipping %s setting - " + "all network protocols are disabled", + VAR_INET_INTERFACES); + return; + } + /* * If we are listening on all interfaces (default), ask the system what * the interfaces are. diff --git a/postfix/src/master/Makefile.in b/postfix/src/master/Makefile.in index a78173916..43f9db57e 100644 --- a/postfix/src/master/Makefile.in +++ b/postfix/src/master/Makefile.in @@ -83,8 +83,10 @@ depend: $(MAKES) @$(EXPORT) make -f Makefile.in Makefile 1>&2 # do not edit below this line - it is generated by 'make depend' +event_server.o: ../../include/argv.h event_server.o: ../../include/chroot_uid.h event_server.o: ../../include/debug_process.h +event_server.o: ../../include/dict.h event_server.o: ../../include/events.h event_server.o: ../../include/iostuff.h event_server.o: ../../include/listen.h @@ -161,6 +163,7 @@ master_ent.o: ../../include/attr.h master_ent.o: ../../include/host_port.h master_ent.o: ../../include/inet_addr_host.h master_ent.o: ../../include/inet_addr_list.h +master_ent.o: ../../include/inet_proto.h master_ent.o: ../../include/iostuff.h master_ent.o: ../../include/mail_conf.h master_ent.o: ../../include/mail_params.h @@ -270,8 +273,10 @@ master_watch.o: ../../include/mymalloc.h master_watch.o: ../../include/sys_defs.h master_watch.o: master.h master_watch.o: master_watch.c +multi_server.o: ../../include/argv.h multi_server.o: ../../include/chroot_uid.h multi_server.o: ../../include/debug_process.h +multi_server.o: ../../include/dict.h multi_server.o: ../../include/events.h multi_server.o: ../../include/iostuff.h multi_server.o: ../../include/listen.h @@ -300,8 +305,10 @@ multi_server.o: mail_flow.h multi_server.o: mail_server.h multi_server.o: master_proto.h multi_server.o: multi_server.c +single_server.o: ../../include/argv.h single_server.o: ../../include/chroot_uid.h single_server.o: ../../include/debug_process.h +single_server.o: ../../include/dict.h single_server.o: ../../include/events.h single_server.o: ../../include/iostuff.h single_server.o: ../../include/listen.h @@ -330,8 +337,10 @@ single_server.o: mail_flow.h single_server.o: mail_server.h single_server.o: master_proto.h single_server.o: single_server.c +trigger_server.o: ../../include/argv.h trigger_server.o: ../../include/chroot_uid.h trigger_server.o: ../../include/debug_process.h +trigger_server.o: ../../include/dict.h trigger_server.o: ../../include/events.h trigger_server.o: ../../include/iostuff.h trigger_server.o: ../../include/listen.h diff --git a/postfix/src/master/master_ent.c b/postfix/src/master/master_ent.c index cc0bb56d7..9441255fa 100644 --- a/postfix/src/master/master_ent.c +++ b/postfix/src/master/master_ent.c @@ -87,6 +87,7 @@ #include #include #include +#include /* Global library. */ @@ -126,6 +127,7 @@ void fset_master_ent(char *path) void set_master_ent() { const char *myname = "set_master_ent"; + char *disable; if (master_fp != 0) msg_panic("%s: configuration file still open", myname); @@ -136,7 +138,16 @@ void set_master_ent() master_line = 0; if (master_disable != 0) msg_panic("%s: service disable list still exists", myname); - master_disable = match_service_init(var_master_disable); + if (inet_proto_info()->ai_family_list[0] == 0) { + msg_warn("all network protocols are disabled (%s = %s)", + VAR_INET_PROTOCOLS, var_inet_protocols); + msg_warn("disabling all type \"inet\" services in master.cf"); + disable = concatenate(MASTER_XPORT_NAME_INET, ",", + var_master_disable, (char *) 0); + master_disable = match_service_init(disable); + myfree(disable); + } else + master_disable = match_service_init(var_master_disable); } /* end_master_ent - close configuration file */ diff --git a/postfix/src/master/master_vars.c b/postfix/src/master/master_vars.c index 3e9b77861..898269f26 100644 --- a/postfix/src/master/master_vars.c +++ b/postfix/src/master/master_vars.c @@ -57,7 +57,6 @@ void master_vars_init(void) { char *path; static const CONFIG_STR_TABLE str_table[] = { - VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 1, 0, VAR_MASTER_DISABLE, DEF_MASTER_DISABLE, &var_master_disable, 0, 0, 0, }; diff --git a/postfix/src/postscreen/Makefile.in b/postfix/src/postscreen/Makefile.in index bf6a735b7..fa7f996ba 100644 --- a/postfix/src/postscreen/Makefile.in +++ b/postfix/src/postscreen/Makefile.in @@ -72,6 +72,7 @@ postscreen.o: ../../include/dict.h postscreen.o: ../../include/dict_cache.h postscreen.o: ../../include/events.h postscreen.o: ../../include/htable.h +postscreen.o: ../../include/inet_proto.h postscreen.o: ../../include/iostuff.h postscreen.o: ../../include/mail_conf.h postscreen.o: ../../include/mail_params.h diff --git a/postfix/src/postscreen/postscreen.c b/postfix/src/postscreen/postscreen.c index 6f2ae065e..36a665bf1 100644 --- a/postfix/src/postscreen/postscreen.c +++ b/postfix/src/postscreen/postscreen.c @@ -384,6 +384,7 @@ #include #include #include +#include /* Global library. */ @@ -592,6 +593,15 @@ static void psc_service(VSTREAM *smtp_client_stream, const char *stamp_str; int saved_flags; + /* + * For sanity, require that at least one of INET or INET6 is enabled. + * Otherwise, we can't look up interface information, and we can't + * convert names or addresses. + */ + if (inet_proto_info()->ai_family_list[0] == 0) + msg_fatal("all network protocols are disabled (%s = %s)", + VAR_INET_PROTOCOLS, var_inet_protocols); + /* * This program handles all incoming connections, so it must not block. * We use event-driven code for all operations that introduce latency. diff --git a/postfix/src/qmqpd/Makefile.in b/postfix/src/qmqpd/Makefile.in index 44bb07109..c180709cf 100644 --- a/postfix/src/qmqpd/Makefile.in +++ b/postfix/src/qmqpd/Makefile.in @@ -63,6 +63,7 @@ qmqpd.o: ../../include/attr.h qmqpd.o: ../../include/cleanup_user.h qmqpd.o: ../../include/debug_peer.h qmqpd.o: ../../include/dict.h +qmqpd.o: ../../include/inet_proto.h qmqpd.o: ../../include/input_transp.h qmqpd.o: ../../include/iostuff.h qmqpd.o: ../../include/lex_822.h diff --git a/postfix/src/qmqpd/qmqpd.c b/postfix/src/qmqpd/qmqpd.c index e9c33e80f..e64bc6ebf 100644 --- a/postfix/src/qmqpd/qmqpd.c +++ b/postfix/src/qmqpd/qmqpd.c @@ -167,6 +167,7 @@ #include #include #include +#include /* Global library. */ @@ -720,6 +721,15 @@ static void qmqpd_service(VSTREAM *stream, char *unused_service, char **argv) if (argv[0]) msg_fatal("unexpected command-line argument: %s", argv[0]); + /* + * For sanity, require that at least one of INET or INET6 is enabled. + * Otherwise, we can't look up interface information, and we can't + * convert names or addresses. + */ + if (inet_proto_info()->ai_family_list[0] == 0) + msg_fatal("all network protocols are disabled (%s = %s)", + VAR_INET_PROTOCOLS, var_inet_protocols); + /* * This routine runs when a client has connected to our network port. * Look up and sanitize the peer name and initialize some connection- diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in index 1d5ed3a6a..cc0aaf58e 100644 --- a/postfix/src/smtp/Makefile.in +++ b/postfix/src/smtp/Makefile.in @@ -224,6 +224,7 @@ smtp_connect.o: ../../include/header_opts.h smtp_connect.o: ../../include/host_port.h smtp_connect.o: ../../include/htable.h smtp_connect.o: ../../include/inet_addr_list.h +smtp_connect.o: ../../include/inet_proto.h smtp_connect.o: ../../include/iostuff.h smtp_connect.o: ../../include/mail_addr.h smtp_connect.o: ../../include/mail_error.h diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 05d59c9f5..2abb49ccb 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -87,6 +87,7 @@ #include #include #include +#include /* Global library. */ @@ -682,10 +683,10 @@ static int smtp_reuse_session(SMTP_STATE *state, int lookup_mx, return (session_count); } -/* smtp_connect_remote - establish remote connection */ +/* smtp_connect_inet - establish network connection */ -static void smtp_connect_remote(SMTP_STATE *state, const char *nexthop, - char *def_service) +static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop, + char *def_service) { DELIVER_REQUEST *request = state->request; ARGV *sites; @@ -695,6 +696,16 @@ static void smtp_connect_remote(SMTP_STATE *state, const char *nexthop, int retry_plain = 0; DSN_BUF *why = state->why; + /* + * For sanity, require that at least one of INET or INET6 is enabled. + * Otherwise, we can't look up interface information, and we can't + * convert names or addresses. + */ + if (inet_proto_info()->ai_family_list[0] == 0) { + dsb_simple(why, "4.4.4", "all network protocols are disabled"); + return; + } + /* * First try to deliver to the indicated destination, then try to deliver * to the optional fall-back relays. @@ -1036,7 +1047,7 @@ int smtp_connect(SMTP_STATE *state) } else { if (strncmp(destination, "inet:", 5) == 0) destination += 5; - smtp_connect_remote(state, destination, DEF_LMTP_SERVICE); + smtp_connect_inet(state, destination, DEF_LMTP_SERVICE); } } @@ -1049,7 +1060,7 @@ int smtp_connect(SMTP_STATE *state) * Postfix configurations that have a host with such a name. */ else { - smtp_connect_remote(state, destination, DEF_SMTP_SERVICE); + smtp_connect_inet(state, destination, DEF_SMTP_SERVICE); } /* diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index 989c3c7ca..f053b1679 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -159,6 +159,7 @@ smtpd.o: ../../include/dsn_mask.h smtpd.o: ../../include/ehlo_mask.h smtpd.o: ../../include/events.h smtpd.o: ../../include/flush_clnt.h +smtpd.o: ../../include/inet_proto.h smtpd.o: ../../include/input_transp.h smtpd.o: ../../include/iostuff.h smtpd.o: ../../include/is_header.h diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 1b3f053c7..6e90bf10d 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1046,6 +1046,7 @@ #include #include #include +#include /* Global library. */ @@ -4812,6 +4813,16 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv) if (argv[0]) msg_fatal("unexpected command-line argument: %s", argv[0]); + /* + * For sanity, require that at least one of INET or INET6 is enabled. + * Otherwise, we can't look up interface information, and we can't + * convert names or addresses. + */ + if (SMTPD_STAND_ALONE_STREAM(stream) == 0 + && inet_proto_info()->ai_family_list[0] == 0) + msg_fatal("all network protocols are disabled (%s = %s)", + VAR_INET_PROTOCOLS, var_inet_protocols); + /* * This routine runs when a client has connected to our network port, or * when the smtp server is run in stand-alone mode (input from pipe). diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 2d6c46c92..4001a8145 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -284,6 +284,9 @@ extern void smtpd_state_reset(SMTPD_STATE *); * If running in stand-alone mode, do not try to talk to Postfix daemons but * write to queue file instead. */ +#define SMTPD_STAND_ALONE_STREAM(stream) \ + (stream == VSTREAM_IN && getuid() != var_owner_uid) + #define SMTPD_STAND_ALONE(state) \ (state->client == VSTREAM_IN && getuid() != var_owner_uid) diff --git a/postfix/src/smtpd/smtpd_peer.c b/postfix/src/smtpd/smtpd_peer.c index 3ea89946b..330e07938 100644 --- a/postfix/src/smtpd/smtpd_peer.c +++ b/postfix/src/smtpd/smtpd_peer.c @@ -372,8 +372,13 @@ void smtpd_peer_init(SMTPD_STATE *state) else { state->name = mystrdup("localhost"); state->reverse_name = mystrdup("localhost"); - state->addr = mystrdup("127.0.0.1"); /* XXX bogus. */ - state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */ + if (proto_info->sa_family_list[0] == PF_INET6) { + state->addr = mystrdup("::1"); /* XXX bogus. */ + state->rfc_addr = mystrdup(IPV6_COL "::1"); /* XXX bogus. */ + } else { + state->addr = mystrdup("127.0.0.1");/* XXX bogus. */ + state->rfc_addr = mystrdup("127.0.0.1"); /* XXX bogus. */ + } state->addr_family = AF_UNSPEC; state->name_status = SMTPD_PEER_CODE_OK; state->reverse_name_status = SMTPD_PEER_CODE_OK; diff --git a/postfix/src/util/inet_proto.c b/postfix/src/util/inet_proto.c index fd082ed07..6b5cc4c2a 100644 --- a/postfix/src/util/inet_proto.c +++ b/postfix/src/util/inet_proto.c @@ -56,7 +56,7 @@ /* One or more of PF_INET or PF_INET6. This can be used as /* input for the inet_addr_local() routine. /* .IP dns_atype_list -/* One or more of T_AAAA or TA. This can be used as input for +/* One or more of T_AAAA or T_A. This can be used as input for /* the dns_lookup_v() and dns_lookup_l() routines. /* .IP sa_family_list /* One or more of AF_INET6 or AF_INET. This can be used as an @@ -65,9 +65,8 @@ /* SEE ALSO /* msg(3) diagnostics interface /* DIAGNOSTICS -/* This module will report if IPv6 is unavailable, and will -/* disable IPv6 support in Postfix. When IPv6 is the only -/* selected protocol, this is a fatal error. +/* This module will warn and turn off support for any protocol +/* that is requested but unavailable. /* /* Fatal errors: memory allocation problem. /* LICENSE @@ -186,46 +185,58 @@ INET_PROTO_INFO *inet_proto_init(const char *context, const char *protocols) int sock; /* - * Store addess family etc. info as null-terminated vectors. If that - * breaks because we must be able to store nulls, we'll deal with the - * additional complexity. - * - * XXX Use compile-time initialized data templates instead of building the - * reply on the fly. + * Avoid run-time errors when all network protocols are disabled. We + * can't look up interface information, and we can't convert explicit + * names or addresses. */ inet_proto_mask = name_mask(context, proto_table, protocols); - switch (inet_proto_mask) { #ifdef HAS_IPV6 - case INET_PROTO_MASK_IPV6: + if (inet_proto_mask & INET_PROTO_MASK_IPV6) { if ((sock = socket(PF_INET6, SOCK_STREAM, 0)) >= 0) { close(sock); - pf = (INET_PROTO_INFO *) mymalloc(sizeof(*pf)); - pf->ai_family = PF_INET6; - pf->ai_family_list = make_unsigned_vector(2, PF_INET6, 0); - pf->dns_atype_list = make_unsigned_vector(2, T_AAAA, 0); - pf->sa_family_list = make_uchar_vector(2, AF_INET6, 0); - break; - } else if (errno == EAFNOSUPPORT) { - msg_fatal("%s: IPv6 support is disabled: %m", context); + } else if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) { + msg_warn("%s: disabling IPv6 name/address support: %m", context); + inet_proto_mask &= ~INET_PROTO_MASK_IPV6; } else { msg_fatal("socket: %m"); } - case (INET_PROTO_MASK_IPV6 | INET_PROTO_MASK_IPV4): - if ((sock = socket(PF_INET6, SOCK_STREAM, 0)) >= 0) { + } +#endif + if (inet_proto_mask & INET_PROTO_MASK_IPV4) { + if ((sock = socket(PF_INET, SOCK_STREAM, 0)) >= 0) { close(sock); - pf = (INET_PROTO_INFO *) mymalloc(sizeof(*pf)); - pf->ai_family = PF_UNSPEC; - pf->ai_family_list = make_unsigned_vector(3, PF_INET, PF_INET6, 0); - pf->dns_atype_list = make_unsigned_vector(3, T_A, T_AAAA, 0); - pf->sa_family_list = make_uchar_vector(3, AF_INET, AF_INET6, 0); - break; } else if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) { - msg_warn("%s: IPv6 support is disabled: %m", context); - msg_warn("%s: configuring for IPv4 support only", context); - /* FALLTHROUGH */ + msg_warn("%s: disabling IPv4 name/address support: %m", context); + inet_proto_mask &= ~INET_PROTO_MASK_IPV4; } else { msg_fatal("socket: %m"); } + } + + /* + * Store addess family etc. info as null-terminated vectors. If that + * breaks because we must be able to store nulls, we'll deal with the + * additional complexity. + * + * XXX Use compile-time initialized data templates instead of building the + * reply on the fly. + */ + switch (inet_proto_mask) { +#ifdef HAS_IPV6 + case INET_PROTO_MASK_IPV6: + pf = (INET_PROTO_INFO *) mymalloc(sizeof(*pf)); + pf->ai_family = PF_INET6; + pf->ai_family_list = make_unsigned_vector(2, PF_INET6, 0); + pf->dns_atype_list = make_unsigned_vector(2, T_AAAA, 0); + pf->sa_family_list = make_uchar_vector(2, AF_INET6, 0); + break; + case (INET_PROTO_MASK_IPV6 | INET_PROTO_MASK_IPV4): + pf = (INET_PROTO_INFO *) mymalloc(sizeof(*pf)); + pf->ai_family = PF_UNSPEC; + pf->ai_family_list = make_unsigned_vector(3, PF_INET, PF_INET6, 0); + pf->dns_atype_list = make_unsigned_vector(3, T_A, T_AAAA, 0); + pf->sa_family_list = make_uchar_vector(3, AF_INET, AF_INET6, 0); + break; #endif case INET_PROTO_MASK_IPV4: pf = (INET_PROTO_INFO *) mymalloc(sizeof(*pf)); @@ -234,6 +245,13 @@ INET_PROTO_INFO *inet_proto_init(const char *context, const char *protocols) pf->dns_atype_list = make_unsigned_vector(2, T_A, 0); pf->sa_family_list = make_uchar_vector(2, AF_INET, 0); break; + case 0: + pf = (INET_PROTO_INFO *) mymalloc(sizeof(*pf)); + pf->ai_family = PF_UNSPEC; + pf->ai_family_list = make_unsigned_vector(1, 0); + pf->dns_atype_list = make_unsigned_vector(1, 0); + pf->sa_family_list = make_uchar_vector(1, 0); + break; default: msg_panic("%s: bad inet_proto_mask 0x%x", myname, inet_proto_mask); } @@ -247,27 +265,58 @@ INET_PROTO_INFO *inet_proto_init(const char *context, const char *protocols) /* * Small driver for unit tests. */ + +static char *print_unsigned_vector(VSTRING *buf, unsigned *vector) +{ + unsigned *p; + + VSTRING_RESET(buf); + for (p = vector; *p; p++) { + vstring_sprintf_append(buf, "%u", *p); + if (p[1]) + VSTRING_ADDCH(buf, ' '); + } + VSTRING_TERMINATE(buf); + return (vstring_str(buf)); +} + +static char *print_uchar_vector(VSTRING *buf, unsigned char *vector) +{ + unsigned char *p; + + VSTRING_RESET(buf); + for (p = vector; *p; p++) { + vstring_sprintf_append(buf, "%u", *p); + if (p[1]) + VSTRING_ADDCH(buf, ' '); + } + VSTRING_TERMINATE(buf); + return (vstring_str(buf)); +} + int main(int argc, char **argv) { const char *myname = argv[0]; INET_PROTO_INFO *pf; + VSTRING *buf; if (argc < 2) msg_fatal("usage: %s protocol(s)...", myname); + buf = vstring_alloc(10); while (*++argv) { msg_info("=== %s ===", *argv); - if (**argv) - inet_proto_init(myname, *argv); + inet_proto_init(myname, *argv); pf = inet_proto_table; msg_info("ai_family = %u", pf->ai_family); - msg_info("ai_family_list = %u %u...", - pf->ai_family_list[0], pf->ai_family_list[1]); - msg_info("dns_atype_list = %u %u...", - pf->dns_atype_list[0], pf->dns_atype_list[1]); - msg_info("sa_family_list = %u %u...", - pf->sa_family_list[0], pf->sa_family_list[1]); + msg_info("ai_family_list = %s", + print_unsigned_vector(buf, pf->ai_family_list)); + msg_info("dns_atype_list = %s", + print_unsigned_vector(buf, pf->dns_atype_list)); + msg_info("sa_family_list = %s", + print_uchar_vector(buf, pf->sa_family_list)); } + vstring_free(buf); return (0); }