mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 09:57:34 +00:00
postfix-3.8-20230312
This commit is contained in:
parent
3474213a2b
commit
d88c99caea
@ -26921,3 +26921,31 @@ Apologies for any names omitted.
|
||||
example is to capture output from "postmulti -p status" to
|
||||
figure out which instances are or are not running. Files:
|
||||
postfix/postfix.c, postlog/postlog.c.
|
||||
|
||||
20230209
|
||||
|
||||
Cleanup: in smtp_service_addr() refined the loop detection
|
||||
code for SRV lookup. File: smtp/smtp_addr.c.
|
||||
|
||||
Cleanup: renamed macros with invisible side effects and
|
||||
implicit inputs to upper case. Verified that the compiled
|
||||
code did not change. File: tls_fprint.c.
|
||||
|
||||
20230310
|
||||
|
||||
Cleanup: the milter header/body checks logged less text (up
|
||||
to 60 bytes) than the 'original' header/body checks (up to
|
||||
200 bytes). Problem reported by Aleksandr Stankevic. Fixed
|
||||
the same inconsistency in the Postfix SMTP client. Files:
|
||||
cleanup/cleanup_milter.c, smtp/smtp_proto.c.
|
||||
|
||||
20230311
|
||||
|
||||
Hardening: the Postfix SMTP server can now aggregate
|
||||
smtpd_client_*_rate and smtpd_client_*_count statistics by
|
||||
network block, as specified with smtpd_client_ipv4_prefix_length
|
||||
(default 32, no aggregation) and smtpd_client_ipv6_prefix_length
|
||||
(default 72, aggregation by /72 network blocks). The latter
|
||||
raises the bar for a memory exhaustion attack. Files:
|
||||
util/net_mask_top.[hc], smtpd/smtpd.c, smtpd/smtpd_peer.c,
|
||||
mantools/postlink, proto/postconf.proto.
|
||||
|
@ -14,6 +14,13 @@ Wish list:
|
||||
Multi-recipient support in sender/recipient_bcc_maps and
|
||||
always_bcc.
|
||||
|
||||
mail_conf_xxx supprt for non-negative numbers (i.e.
|
||||
numbers with a lower bound of zero).
|
||||
|
||||
Log anvil transgressions with their address range (in
|
||||
addition to the offending IP address. We should not disclose
|
||||
to random clients how we aggregate anvil event counters.
|
||||
|
||||
Should "postconf -f" pretty-print text inside {}?
|
||||
|
||||
Is there any code that calls attr_scan*() and that works
|
||||
|
@ -14639,6 +14639,33 @@ This feature is available in Postfix 2.2 and later.
|
||||
</p>
|
||||
|
||||
|
||||
</DD>
|
||||
|
||||
<DT><b><a name="smtpd_client_ipv4_prefix_length">smtpd_client_ipv4_prefix_length</a>
|
||||
(default: 32)</b></DT><DD>
|
||||
|
||||
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv4 network blocks with the specified network prefix. Aggregation
|
||||
reduces the <a href="anvil.8.html">anvil(8)</a> resources needed to maintain counters. By
|
||||
default, aggregation is disabled for IPv4. </p>
|
||||
|
||||
<p> This feature is available in Postfix 3.8 and later. </p>
|
||||
|
||||
|
||||
</DD>
|
||||
|
||||
<DT><b><a name="smtpd_client_ipv6_prefix_length">smtpd_client_ipv6_prefix_length</a>
|
||||
(default: 72)</b></DT><DD>
|
||||
|
||||
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv6 network blocks with the specified network prefix. Aggregation
|
||||
reduces the <a href="anvil.8.html">anvil(8)</a> resources needed to maintain counters. By
|
||||
default, aggregation is enabled for IPv6.
|
||||
</p>
|
||||
|
||||
<p> This feature is available in Postfix 3.8 and later. </p>
|
||||
|
||||
|
||||
</DD>
|
||||
|
||||
<DT><b><a name="smtpd_client_message_rate_limit">smtpd_client_message_rate_limit</a>
|
||||
|
@ -962,6 +962,16 @@ SMTPD(8) SMTPD(8)
|
||||
<b><a href="postconf.5.html#header_from_format">header_from_format</a> (standard)</b>
|
||||
The format of the Postfix-generated <b>From:</b> header.
|
||||
|
||||
Available in Postfix version 3.8 and later:
|
||||
|
||||
<b><a href="postconf.5.html#smtpd_client_ipv4_prefix_length">smtpd_client_ipv4_prefix_length</a> (32)</b>
|
||||
Aggregate smtpd_client_*_count and smtpd_client_*_rate statis-
|
||||
tics by IPv4 network blocks with the specified network prefix.
|
||||
|
||||
<b><a href="postconf.5.html#smtpd_client_ipv6_prefix_length">smtpd_client_ipv6_prefix_length</a> (72)</b>
|
||||
Aggregate smtpd_client_*_count and smtpd_client_*_rate statis-
|
||||
tics by IPv6 network blocks with the specified network prefix.
|
||||
|
||||
<b>TARPIT CONTROLS</b>
|
||||
When a remote SMTP client makes errors, the Postfix SMTP server can
|
||||
insert delays before responding. This can help to slow down run-away
|
||||
|
@ -9956,6 +9956,20 @@ parent_domain_matches_subdomains parameter value (Postfix 3.0 and
|
||||
later).
|
||||
.PP
|
||||
This feature is available in Postfix 2.2 and later.
|
||||
.SH smtpd_client_ipv4_prefix_length (default: 32)
|
||||
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv4 network blocks with the specified network prefix. Aggregation
|
||||
reduces the \fBanvil\fR(8) resources needed to maintain counters. By
|
||||
default, aggregation is disabled for IPv4.
|
||||
.PP
|
||||
This feature is available in Postfix 3.8 and later.
|
||||
.SH smtpd_client_ipv6_prefix_length (default: 72)
|
||||
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv6 network blocks with the specified network prefix. Aggregation
|
||||
reduces the \fBanvil\fR(8) resources needed to maintain counters. By
|
||||
default, aggregation is enabled for IPv6.
|
||||
.PP
|
||||
This feature is available in Postfix 3.8 and later.
|
||||
.SH smtpd_client_message_rate_limit (default: 0)
|
||||
The maximal number of message delivery requests that any client is
|
||||
allowed to make to this service per time unit, regardless of whether
|
||||
|
@ -841,6 +841,14 @@ DATA and BDAT requests, when deadlines are enabled with
|
||||
smtpd_per_request_deadline.
|
||||
.IP "\fBheader_from_format (standard)\fR"
|
||||
The format of the Postfix\-generated \fBFrom:\fR header.
|
||||
.PP
|
||||
Available in Postfix version 3.8 and later:
|
||||
.IP "\fBsmtpd_client_ipv4_prefix_length (32)\fR"
|
||||
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv4 network blocks with the specified network prefix.
|
||||
.IP "\fBsmtpd_client_ipv6_prefix_length (72)\fR"
|
||||
Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv6 network blocks with the specified network prefix.
|
||||
.SH "TARPIT CONTROLS"
|
||||
.na
|
||||
.nf
|
||||
|
@ -543,6 +543,8 @@ while (<>) {
|
||||
s;\bsmtpd_client_port_logging\b;<a href="postconf.5.html#smtpd_client_port_logging">$&</a>;g;
|
||||
s;\bsmtpd_client_recipient_rate_limit\b;<a href="postconf.5.html#smtpd_client_recipient_rate_limit">$&</a>;g;
|
||||
s;\bsmtpd_client_new_tls_session_rate_limit\b;<a href="postconf.5.html#smtpd_client_new_tls_session_rate_limit">$&</a>;g;
|
||||
s;\bsmtpd_client_ipv4_prefix_length\b;<a href="postconf.5.html#smtpd_client_ipv4_prefix_length">$&</a>;g;
|
||||
s;\bsmtpd_client_ipv6_prefix_length\b;<a href="postconf.5.html#smtpd_client_ipv6_prefix_length">$&</a>;g;
|
||||
s;\bsmtpd_client_restrictions\b;<a href="postconf.5.html#smtpd_client_restrictions">$&</a>;g;
|
||||
s;\bsmtpd_command_filter\b;<a href="postconf.5.html#smtpd_command_filter">$&</a>;g;
|
||||
s;\bsmtpd_data_restrictions\b;<a href="postconf.5.html#smtpd_data_restrictions">$&</a>;g;
|
||||
|
@ -18598,3 +18598,22 @@ lookup as if SRV record lookup was not enabled. </p>
|
||||
to MX or IP address lookup as if SRV record lookup was not enabled. <p>
|
||||
|
||||
<p> This feature is available in Postfix 3.8 and later. </p>
|
||||
|
||||
%PARAM smtpd_client_ipv4_prefix_length 32
|
||||
|
||||
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv4 network blocks with the specified network prefix. Aggregation
|
||||
reduces the anvil(8) resources needed to maintain counters. By
|
||||
default, aggregation is disabled for IPv4. </p>
|
||||
|
||||
<p> This feature is available in Postfix 3.8 and later. </p>
|
||||
|
||||
%PARAM smtpd_client_ipv6_prefix_length 72
|
||||
|
||||
<p> Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
by IPv6 network blocks with the specified network prefix. Aggregation
|
||||
reduces the anvil(8) resources needed to maintain counters. By
|
||||
default, aggregation is enabled for IPv6.
|
||||
</p>
|
||||
|
||||
<p> This feature is available in Postfix 3.8 and later. </p>
|
||||
|
@ -331,3 +331,4 @@ USE_FNV_32BIT USE_FNV_32BIT
|
||||
void void cleanup_milter_receive state count
|
||||
struct DICT open const char int int dict_xx_open
|
||||
Available in in Postfix version 2 3 3 7
|
||||
length length of 0 31 0 127
|
||||
|
@ -35,3 +35,4 @@ proto proto SASL_README html proto SQLITE_README html
|
||||
tls tls_proxy h tlsproxy tlsproxy c
|
||||
postfix postfix c postlog postlog c
|
||||
postfix postfix c postlog postlog c
|
||||
util net_mask_top hc smtpd smtpd c smtpd smtpd_peer c
|
||||
|
@ -1793,3 +1793,6 @@ Korbar
|
||||
ign
|
||||
noport
|
||||
nopref
|
||||
ADDRP
|
||||
iffalse
|
||||
iftrue
|
||||
|
@ -47,3 +47,5 @@ modernisms
|
||||
Bordo
|
||||
css
|
||||
makemanidx
|
||||
soho
|
||||
soho
|
||||
|
@ -244,7 +244,7 @@ static void cleanup_milter_hbc_log(void *context, const char *action,
|
||||
const CLEANUP_STATE *state = (CLEANUP_STATE *) context;
|
||||
const char *attr;
|
||||
|
||||
vstring_sprintf(state->temp1, "%s: milter-%s-%s: %s %.60s from %s[%s];",
|
||||
vstring_sprintf(state->temp1, "%s: milter-%s-%s: %s %.200s from %s[%s];",
|
||||
state->queue_id, where, action, where, line,
|
||||
state->client_name, state->client_addr);
|
||||
if (state->sender)
|
||||
|
@ -3198,6 +3198,16 @@ extern int var_smtpd_cntls_limit;
|
||||
#define DEF_SMTPD_CAUTH_LIMIT 0
|
||||
extern int var_smtpd_cauth_limit;
|
||||
|
||||
#define VAR_SMTPD_CIPV4_PREFIX "smtpd_client_ipv4_prefix_length"
|
||||
#define DEF_SMTPD_CIPV4_PREFIX 32
|
||||
#define MAX_SMTPD_CIPV4_PREFIX 32
|
||||
extern int var_smtpd_cipv4_prefix;
|
||||
|
||||
#define VAR_SMTPD_CIPV6_PREFIX "smtpd_client_ipv6_prefix_length"
|
||||
#define DEF_SMTPD_CIPV6_PREFIX 72
|
||||
#define MAX_SMTPD_CIPV6_PREFIX 128
|
||||
extern int var_smtpd_cipv6_prefix;
|
||||
|
||||
#define VAR_SMTPD_HOGGERS "smtpd_client_event_limit_exceptions"
|
||||
#define DEF_SMTPD_HOGGERS "${smtpd_client_connection_limit_exceptions:$" VAR_MYNETWORKS "}"
|
||||
extern char *var_smtpd_hoggers;
|
||||
|
@ -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 "20230308"
|
||||
#define MAIL_RELEASE_DATE "20230312"
|
||||
#define MAIL_VERSION_NUMBER "3.8"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -840,7 +840,6 @@ DNS_RR *smtp_service_addr(const char *name, const char *service, DNS_RR **mxrr,
|
||||
dsb_status(why, "5.4.4");
|
||||
break;
|
||||
}
|
||||
*found_myself |= (self != 0);
|
||||
|
||||
/*
|
||||
* If permitted, fall back to non-SRV record lookups.
|
||||
@ -854,5 +853,12 @@ DNS_RR *smtp_service_addr(const char *name, const char *service, DNS_RR **mxrr,
|
||||
else
|
||||
addr_list = smtp_host_addr(name, misc_flags, why);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only if we're not falling back.
|
||||
*/
|
||||
else {
|
||||
*found_myself |= (self != 0);
|
||||
}
|
||||
return (addr_list);
|
||||
}
|
||||
|
@ -1146,10 +1146,10 @@ static void smtp_hbc_logger(void *context, const char *action,
|
||||
const SMTP_STATE *state = (SMTP_STATE *) context;
|
||||
|
||||
if (*text) {
|
||||
msg_info("%s: %s: %s %.60s: %s",
|
||||
msg_info("%s: %s: %s %.200s: %s",
|
||||
state->request->queue_id, action, where, content, text);
|
||||
} else {
|
||||
msg_info("%s: %s: %s %.60s",
|
||||
msg_info("%s: %s: %s %.200s",
|
||||
state->request->queue_id, action, where, content);
|
||||
}
|
||||
}
|
||||
|
@ -492,6 +492,7 @@ smtpd_peer.o: ../../include/myaddrinfo.h
|
||||
smtpd_peer.o: ../../include/mymalloc.h
|
||||
smtpd_peer.o: ../../include/name_code.h
|
||||
smtpd_peer.o: ../../include/name_mask.h
|
||||
smtpd_peer.o: ../../include/net_mask_top.h
|
||||
smtpd_peer.o: ../../include/nvtable.h
|
||||
smtpd_peer.o: ../../include/sock_addr.h
|
||||
smtpd_peer.o: ../../include/split_at.h
|
||||
|
@ -795,6 +795,14 @@
|
||||
/* smtpd_per_request_deadline.
|
||||
/* .IP "\fBheader_from_format (standard)\fR"
|
||||
/* The format of the Postfix-generated \fBFrom:\fR header.
|
||||
/* .PP
|
||||
/* Available in Postfix version 3.8 and later:
|
||||
/* .IP "\fBsmtpd_client_ipv4_prefix_length (32)\fR"
|
||||
/* Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
/* by IPv4 network blocks with the specified network prefix.
|
||||
/* .IP "\fBsmtpd_client_ipv6_prefix_length (72)\fR"
|
||||
/* Aggregate smtpd_client_*_count and smtpd_client_*_rate statistics
|
||||
/* by IPv6 network blocks with the specified network prefix.
|
||||
/* TARPIT CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -1411,6 +1419,8 @@ int var_smtpd_cmail_limit;
|
||||
int var_smtpd_crcpt_limit;
|
||||
int var_smtpd_cntls_limit;
|
||||
int var_smtpd_cauth_limit;
|
||||
int var_smtpd_cipv4_prefix;
|
||||
int var_smtpd_cipv6_prefix;
|
||||
char *var_smtpd_hoggers;
|
||||
char *var_local_rwr_clients;
|
||||
char *var_smtpd_ehlo_dis_words;
|
||||
@ -2054,7 +2064,7 @@ static int smtpd_sasl_auth_cmd_wrapper(SMTPD_STATE *state, int argc,
|
||||
&& anvil_clnt
|
||||
&& var_smtpd_cauth_limit > 0
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_auth(anvil_clnt, state->service, state->addr,
|
||||
&& anvil_clnt_auth(anvil_clnt, state->service, state->anvil_range,
|
||||
&rate) == ANVIL_STAT_OK
|
||||
&& rate > var_smtpd_cauth_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
@ -2512,7 +2522,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
&& anvil_clnt
|
||||
&& var_smtpd_cmail_limit > 0
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_mail(anvil_clnt, state->service, state->addr,
|
||||
&& anvil_clnt_mail(anvil_clnt, state->service, state->anvil_range,
|
||||
&rate) == ANVIL_STAT_OK
|
||||
&& rate > var_smtpd_cmail_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
@ -2906,7 +2916,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
&& anvil_clnt
|
||||
&& var_smtpd_crcpt_limit > 0
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->addr,
|
||||
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->anvil_range,
|
||||
&rate) == ANVIL_STAT_OK
|
||||
&& rate > var_smtpd_crcpt_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
@ -4230,7 +4240,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
||||
&& anvil_clnt
|
||||
&& var_smtpd_crcpt_limit > 0
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->addr,
|
||||
&& anvil_clnt_rcpt(anvil_clnt, state->service, state->anvil_range,
|
||||
&rate) == ANVIL_STAT_OK
|
||||
&& rate > var_smtpd_crcpt_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
@ -5146,7 +5156,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
|
||||
&& !xclient_allowed
|
||||
&& anvil_clnt
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_newtls(anvil_clnt, state->service, state->addr,
|
||||
&& anvil_clnt_newtls(anvil_clnt, state->service, state->anvil_range,
|
||||
&rate) == ANVIL_STAT_OK
|
||||
&& rate > var_smtpd_cntls_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
@ -5292,8 +5302,8 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
&& !xclient_allowed
|
||||
&& anvil_clnt
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_newtls_stat(anvil_clnt, state->service, state->addr,
|
||||
&rate) == ANVIL_STAT_OK
|
||||
&& anvil_clnt_newtls_stat(anvil_clnt, state->service,
|
||||
state->anvil_range, &rate) == ANVIL_STAT_OK
|
||||
&& rate > var_smtpd_cntls_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
msg_warn("Refusing STARTTLS request from %s for service %s",
|
||||
@ -5560,7 +5570,7 @@ static void smtpd_proto(SMTPD_STATE *state)
|
||||
&& anvil_clnt
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_newtls_stat(anvil_clnt, state->service,
|
||||
state->addr, &tls_rate) == ANVIL_STAT_OK
|
||||
state->anvil_range, &tls_rate) == ANVIL_STAT_OK
|
||||
&& tls_rate > var_smtpd_cntls_limit) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
msg_warn("Refusing TLS service request from %s for service %s",
|
||||
@ -5586,8 +5596,9 @@ static void smtpd_proto(SMTPD_STATE *state)
|
||||
&& !xclient_allowed
|
||||
&& anvil_clnt
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr)
|
||||
&& anvil_clnt_connect(anvil_clnt, state->service, state->addr,
|
||||
&state->conn_count, &state->conn_rate)
|
||||
&& anvil_clnt_connect(anvil_clnt, state->service,
|
||||
state->anvil_range, &state->conn_count,
|
||||
&state->conn_rate)
|
||||
== ANVIL_STAT_OK) {
|
||||
if (var_smtpd_cconn_limit > 0
|
||||
&& state->conn_count > var_smtpd_cconn_limit) {
|
||||
@ -5845,7 +5856,7 @@ static void smtpd_proto(SMTPD_STATE *state)
|
||||
&& !xclient_allowed
|
||||
&& anvil_clnt
|
||||
&& !namadr_list_match(hogger_list, state->name, state->addr))
|
||||
anvil_clnt_disconnect(anvil_clnt, state->service, state->addr);
|
||||
anvil_clnt_disconnect(anvil_clnt, state->service, state->anvil_range);
|
||||
|
||||
/*
|
||||
* Log abnormal session termination, in case postmaster notification has
|
||||
@ -6427,6 +6438,8 @@ int main(int argc, char **argv)
|
||||
VAR_SMTPD_CRCPT_LIMIT, DEF_SMTPD_CRCPT_LIMIT, &var_smtpd_crcpt_limit, 0, 0,
|
||||
VAR_SMTPD_CNTLS_LIMIT, DEF_SMTPD_CNTLS_LIMIT, &var_smtpd_cntls_limit, 0, 0,
|
||||
VAR_SMTPD_CAUTH_LIMIT, DEF_SMTPD_CAUTH_LIMIT, &var_smtpd_cauth_limit, 0, 0,
|
||||
VAR_SMTPD_CIPV4_PREFIX, DEF_SMTPD_CIPV4_PREFIX, &var_smtpd_cipv4_prefix, 0, MAX_SMTPD_CIPV4_PREFIX,
|
||||
VAR_SMTPD_CIPV6_PREFIX, DEF_SMTPD_CIPV6_PREFIX, &var_smtpd_cipv6_prefix, 0, MAX_SMTPD_CIPV6_PREFIX,
|
||||
#ifdef USE_TLS
|
||||
VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
|
||||
#endif
|
||||
|
@ -77,6 +77,7 @@ typedef struct {
|
||||
char *addr; /* client host address string */
|
||||
char *port; /* port for logging */
|
||||
char *namaddr; /* name[address]:port */
|
||||
char *anvil_range; /* client address or network/length */
|
||||
char *rfc_addr; /* address for RFC 2821 */
|
||||
int addr_family; /* address family */
|
||||
char *dest_addr; /* Dovecot AUTH, Milter {daemon_addr} */
|
||||
|
@ -139,6 +139,7 @@
|
||||
#include <sock_addr.h>
|
||||
#include <inet_proto.h>
|
||||
#include <split_at.h>
|
||||
#include <net_mask_top.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
@ -250,10 +251,12 @@ static int smtpd_peer_sockaddr_to_hostaddr(SMTPD_STATE *state)
|
||||
state->addr = mystrdup(colonp + 1);
|
||||
state->rfc_addr = mystrdup(colonp + 1);
|
||||
state->addr_family = AF_INET;
|
||||
aierr = hostaddr_to_sockaddr(state->addr, (char *) 0, 0, &res0);
|
||||
aierr =
|
||||
hostaddr_to_sockaddr(state->addr, state->port, 0, &res0);
|
||||
if (aierr)
|
||||
msg_fatal("%s: cannot convert %s from string to binary: %s",
|
||||
myname, state->addr, MAI_STRERROR(aierr));
|
||||
msg_fatal("%s: cannot convert [%s]:%s to binary: %s",
|
||||
myname, state->addr, state->port,
|
||||
MAI_STRERROR(aierr));
|
||||
sa_length = res0->ai_addrlen;
|
||||
if (sa_length > sizeof(state->sockaddr))
|
||||
sa_length = sizeof(state->sockaddr);
|
||||
@ -264,10 +267,10 @@ static int smtpd_peer_sockaddr_to_hostaddr(SMTPD_STATE *state)
|
||||
/*
|
||||
* Following RFC 2821 section 4.1.3, an IPv6 address literal gets
|
||||
* a prefix of 'IPv6:'. We do this consistently for all IPv6
|
||||
* addresses that appear in headers or envelopes. The fact
|
||||
* that valid_mailhost_addr() enforces the form helps of course.
|
||||
* We use the form without IPV6: prefix when doing access
|
||||
* control, or when accessing the connection cache.
|
||||
* addresses that appear in headers or envelopes. The fact that
|
||||
* valid_mailhost_addr() enforces the form helps of course. We
|
||||
* use the form without IPV6: prefix when doing access control,
|
||||
* or when accessing the connection cache.
|
||||
*/
|
||||
else {
|
||||
state->addr = mystrdup(client_addr.buf);
|
||||
@ -581,6 +584,7 @@ static void smtpd_peer_from_proxy(SMTPD_STATE *state)
|
||||
|
||||
void smtpd_peer_init(SMTPD_STATE *state)
|
||||
{
|
||||
int af;
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
@ -599,6 +603,7 @@ void smtpd_peer_init(SMTPD_STATE *state)
|
||||
state->namaddr = 0;
|
||||
state->rfc_addr = 0;
|
||||
state->port = 0;
|
||||
state->anvil_range = 0;
|
||||
state->dest_addr = 0;
|
||||
state->dest_port = 0;
|
||||
|
||||
@ -633,6 +638,16 @@ void smtpd_peer_init(SMTPD_STATE *state)
|
||||
*/
|
||||
state->namaddr = SMTPD_BUILD_NAMADDRPORT(state->name, state->addr,
|
||||
state->port);
|
||||
|
||||
/*
|
||||
* Generate 'address' or 'net/mask' index for anvil event aggregation.
|
||||
*/
|
||||
af = SOCK_ADDR_FAMILY(&(state->sockaddr));
|
||||
state->anvil_range = net_mask_top(af,
|
||||
SOCK_ADDR_ADDRP(&(state->sockaddr)),
|
||||
af == AF_INET ?
|
||||
var_smtpd_cipv4_prefix :
|
||||
var_smtpd_cipv6_prefix);
|
||||
}
|
||||
|
||||
/* smtpd_peer_reset - destroy peer information */
|
||||
@ -655,4 +670,6 @@ void smtpd_peer_reset(SMTPD_STATE *state)
|
||||
myfree(state->dest_addr);
|
||||
if (state->dest_port)
|
||||
myfree(state->dest_port);
|
||||
if (state->anvil_range)
|
||||
myfree(state->anvil_range);
|
||||
}
|
||||
|
@ -130,11 +130,11 @@
|
||||
|
||||
static const char hexcodes[] = "0123456789ABCDEF";
|
||||
|
||||
#define checkok(stillok) (ok = ok && (stillok))
|
||||
#define digest_object(p) digest_data((unsigned char *)(p), sizeof(*(p)))
|
||||
#define digest_data(p, l) checkok(digest_bytes(mdctx, (p), (l)))
|
||||
#define digest_string(s) checkok(digest_chars(mdctx, (s)))
|
||||
#define digest_dane(tlsa) checkok(tls_digest_tlsa(mdctx, tlsa))
|
||||
#define CHECK_OK_AND(stillok) (ok = ok && (stillok))
|
||||
#define CHECK_OK_AND_DIGEST_OBJECT(m, p) \
|
||||
CHECK_OK_AND_DIGEST_DATA((m), (unsigned char *)(p), sizeof(*(p)))
|
||||
#define CHECK_OK_AND_DIGEST_DATA(m, p, l) CHECK_OK_AND(digest_bytes((m), (p), (l)))
|
||||
#define CHECK_OK_AND_DIGEST_CHARS(m, s) CHECK_OK_AND(digest_chars((m), (s)))
|
||||
|
||||
/* digest_bytes - hash octet string of given length */
|
||||
|
||||
@ -186,13 +186,13 @@ static int tls_digest_tlsa(EVP_MD_CTX *mdctx, TLS_TLSA *tlsa)
|
||||
arr[i++] = (void *) p;
|
||||
qsort(arr, n, sizeof(arr[0]), tlsa_cmp);
|
||||
|
||||
digest_object(&n);
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &n);
|
||||
for (i = 0; i < n; ++i) {
|
||||
digest_object(&arr[i]->usage);
|
||||
digest_object(&arr[i]->selector);
|
||||
digest_object(&arr[i]->mtype);
|
||||
digest_object(&arr[i]->length);
|
||||
digest_data(arr[i]->data, arr[i]->length);
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->usage);
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->selector);
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->mtype);
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &arr[i]->length);
|
||||
CHECK_OK_AND_DIGEST_DATA(mdctx, arr[i]->data, arr[i]->length);
|
||||
}
|
||||
myfree((void *) arr);
|
||||
return (ok);
|
||||
@ -218,15 +218,15 @@ const EVP_MD *tls_digest_byname(const char *mdalg, EVP_MD_CTX **mdctxPtr)
|
||||
* Note that EVP_MD_CTX_{create,destroy} were renamed to, respectively,
|
||||
* EVP_MD_CTX_{new,free} in OpenSSL 1.1.0.
|
||||
*/
|
||||
checkok(md = EVP_get_digestbyname(mdalg));
|
||||
CHECK_OK_AND(md = EVP_get_digestbyname(mdalg));
|
||||
|
||||
/*
|
||||
* Sanity check: Newer shared libraries could (hypothetical ABI break)
|
||||
* allow larger digests, we avoid such poison algorithms.
|
||||
*/
|
||||
checkok(EVP_MD_size(md) <= EVP_MAX_MD_SIZE);
|
||||
checkok(mdctx = EVP_MD_CTX_new());
|
||||
checkok(EVP_DigestInit_ex(mdctx, md, NULL));
|
||||
CHECK_OK_AND(EVP_MD_size(md) <= EVP_MAX_MD_SIZE);
|
||||
CHECK_OK_AND(mdctx = EVP_MD_CTX_new());
|
||||
CHECK_OK_AND(EVP_DigestInit_ex(mdctx, md, NULL));
|
||||
|
||||
|
||||
if (ok && mdctxPtr != 0)
|
||||
@ -269,10 +269,10 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
|
||||
/* Salt the session lookup key with the OpenSSL runtime version. */
|
||||
sslversion = OpenSSL_version_num();
|
||||
|
||||
digest_string(props->helo ? props->helo : "");
|
||||
digest_object(&sslversion);
|
||||
digest_string(props->protocols);
|
||||
digest_string(ciphers);
|
||||
CHECK_OK_AND_DIGEST_CHARS(mdctx, props->helo ? props->helo : "");
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &sslversion);
|
||||
CHECK_OK_AND_DIGEST_CHARS(mdctx, props->protocols);
|
||||
CHECK_OK_AND_DIGEST_CHARS(mdctx, ciphers);
|
||||
|
||||
/*
|
||||
* Ensure separation of caches for sessions where DANE trust
|
||||
@ -280,7 +280,7 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
|
||||
* should always see a certificate validation failure, both on initial
|
||||
* handshake and on resumption.
|
||||
*/
|
||||
digest_object(&TLScontext->must_fail);
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &TLScontext->must_fail);
|
||||
|
||||
/*
|
||||
* DNS-based or synthetic DANE trust settings are potentially used at all
|
||||
@ -288,11 +288,11 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
|
||||
*/
|
||||
if (TLScontext->level > TLS_LEV_ENCRYPT
|
||||
&& props->dane && props->dane->tlsa) {
|
||||
digest_dane(props->dane->tlsa);
|
||||
CHECK_OK_AND(tls_digest_tlsa(mdctx, props->dane->tlsa));
|
||||
} else {
|
||||
int none = 0; /* Record a TLSA RR count of zero */
|
||||
|
||||
digest_object(&none);
|
||||
CHECK_OK_AND_DIGEST_OBJECT(mdctx, &none);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -300,11 +300,11 @@ char *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
|
||||
* selection.
|
||||
*/
|
||||
if (TLScontext->level > TLS_LEV_ENCRYPT && TLScontext->peer_sni)
|
||||
digest_string(TLScontext->peer_sni);
|
||||
CHECK_OK_AND_DIGEST_CHARS(mdctx, TLScontext->peer_sni);
|
||||
else
|
||||
digest_string("");
|
||||
CHECK_OK_AND_DIGEST_CHARS(mdctx, "");
|
||||
|
||||
checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
|
||||
CHECK_OK_AND(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
if (!ok)
|
||||
msg_fatal("error computing %s message digest", mdalg);
|
||||
@ -368,8 +368,8 @@ static char *tls_data_fprint(const unsigned char *buf, int len, const char *mdal
|
||||
if (tls_digest_byname(mdalg, &mdctx) == 0)
|
||||
msg_panic("digest algorithm \"%s\" not found", mdalg);
|
||||
|
||||
digest_data(buf, len);
|
||||
checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
|
||||
CHECK_OK_AND_DIGEST_DATA(mdctx, buf, len);
|
||||
CHECK_OK_AND(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
if (!ok)
|
||||
msg_fatal("error computing %s message digest", mdalg);
|
||||
|
@ -44,7 +44,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
|
||||
msg_logger.c logwriter.c unix_dgram_connect.c unix_dgram_listen.c \
|
||||
byte_mask.c known_tcp_ports.c argv_split_at.c dict_stream.c \
|
||||
sane_strtol.c hash_fnv.c ldseed.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c \
|
||||
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c
|
||||
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c net_mask_top.c
|
||||
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
||||
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
|
||||
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
||||
@ -90,7 +90,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
||||
msg_logger.o logwriter.o unix_dgram_connect.o unix_dgram_listen.o \
|
||||
byte_mask.o known_tcp_ports.o argv_split_at.o dict_stream.o \
|
||||
sane_strtol.o hash_fnv.o ldseed.o mkmap_db.o mkmap_dbm.o \
|
||||
mkmap_fail.o mkmap_open.o
|
||||
mkmap_fail.o mkmap_open.o net_mask_top.o
|
||||
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
|
||||
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
|
||||
# otherwise it sets the PLUGIN_* macros.
|
||||
@ -121,7 +121,8 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
|
||||
slmdb.h compat_va_copy.h dict_pipe.h dict_random.h \
|
||||
valid_utf8_hostname.h midna_domain.h dict_union.h dict_inline.h \
|
||||
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
|
||||
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h
|
||||
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \
|
||||
net_mask_top.h
|
||||
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
|
||||
stream_test.c dup2_pass_on_exec.c
|
||||
DEFS = -I. -D$(SYSTYPE)
|
||||
@ -2415,6 +2416,15 @@ nbbio.o: mymalloc.h
|
||||
nbbio.o: nbbio.c
|
||||
nbbio.o: nbbio.h
|
||||
nbbio.o: sys_defs.h
|
||||
net_mask_top.o: check_arg.h
|
||||
net_mask_top.o: mask_addr.h
|
||||
net_mask_top.o: msg.h
|
||||
net_mask_top.o: myaddrinfo.h
|
||||
net_mask_top.o: net_mask_top.c
|
||||
net_mask_top.o: net_mask_top.h
|
||||
net_mask_top.o: sys_defs.h
|
||||
net_mask_top.o: vbuf.h
|
||||
net_mask_top.o: vstring.h
|
||||
netstring.o: check_arg.h
|
||||
netstring.o: compat_va_copy.h
|
||||
netstring.o: msg.h
|
||||
|
120
postfix/src/util/net_mask_top.c
Normal file
120
postfix/src/util/net_mask_top.c
Normal file
@ -0,0 +1,120 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* net_mask_top 3
|
||||
/* SUMMARY
|
||||
/* convert net/mask to printable string
|
||||
/* SYNOPSIS
|
||||
/* #include <mask_addr.h>
|
||||
/*
|
||||
/* char *net_mask_top(
|
||||
/* int family,
|
||||
/* const void *src,
|
||||
/* int prefix_len)
|
||||
/* DESCRIPTION
|
||||
/* net_mask_top() prints the network portion of the specified
|
||||
/* IPv4 or IPv6 address, null bits for the host portion, and
|
||||
/* the prefix length if it is shorter than the address.
|
||||
/* The result should be passed to myfree(). The code can
|
||||
/* handle addresses of any length, and bytes of any width.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP af
|
||||
/* The address family, as with inet_ntop().
|
||||
/* .IP src
|
||||
/* Pointer to storage for an IPv4 or IPv6 address, as with
|
||||
/* inet_ntop().
|
||||
/* .IP prefix_len
|
||||
/* The number of most-significant bits in \fBsrc\fR that should
|
||||
/* not be cleared.
|
||||
/* DIAGNOSTICS
|
||||
/* Panic: unexpected protocol family, bad prefix length. Fatal
|
||||
/* errors: address conversion error.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/*--*/
|
||||
|
||||
/*
|
||||
* System library.
|
||||
*/
|
||||
#include <sys_defs.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Utility library.
|
||||
*/
|
||||
#include <mask_addr.h>
|
||||
#include <msg.h>
|
||||
#include <myaddrinfo.h>
|
||||
#include <net_mask_top.h>
|
||||
#include <vstring.h>
|
||||
|
||||
/*
|
||||
* XXX Factor out if we also need this in other places.
|
||||
*/
|
||||
struct addr_size {
|
||||
int af; /* address family (binary) */
|
||||
char ipproto_str[5]; /* IP protocol version (string) */
|
||||
int addr_bitcount; /* bits per address */
|
||||
int addr_bytecount; /* bytes per address */
|
||||
int addr_strlen; /* string representation length */
|
||||
int slashdigs_strlen; /* length of /0-31, /0-127 */
|
||||
};
|
||||
static struct addr_size addr_sizes[] = {
|
||||
AF_INET, "IPv4", MAI_V4ADDR_BITS, MAI_V4ADDR_BYTES, INET_ADDRSTRLEN, 3,
|
||||
#ifdef HAS_IPV6
|
||||
AF_INET6, "IPv6", MAI_V6ADDR_BITS, MAI_V6ADDR_BYTES, INET6_ADDRSTRLEN, 4,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* get_addr_size - get bit-banging numbers for address family */
|
||||
|
||||
static struct addr_size *get_addr_size(int af)
|
||||
{
|
||||
struct addr_size *ap;
|
||||
|
||||
for (ap = addr_sizes; /* see below */ ; ap++) {
|
||||
if (ap >= addr_sizes + sizeof(addr_sizes) / sizeof(struct addr_size))
|
||||
return (0);
|
||||
if (ap->af == af)
|
||||
return (ap);
|
||||
}
|
||||
}
|
||||
|
||||
/* net_mask_top - printable net/mask pattern */
|
||||
|
||||
char *net_mask_top(int af, const void *src, int prefix_len)
|
||||
{
|
||||
const char myname[] = "net_mask_top";
|
||||
union {
|
||||
struct in_addr in_addr;
|
||||
struct in6_addr in6_addr;
|
||||
} u;
|
||||
VSTRING *buf;
|
||||
struct addr_size *ap;
|
||||
|
||||
if ((ap = get_addr_size(af)) == 0)
|
||||
msg_panic("%s: unexpected address family: %d", myname, af);
|
||||
if (prefix_len > ap->addr_bitcount || prefix_len < 0)
|
||||
msg_fatal("%s: bad %s address prefix length: %d",
|
||||
myname, ap->ipproto_str, prefix_len);
|
||||
memcpy((void *) &u, src, ap->addr_bytecount);
|
||||
if (prefix_len < ap->addr_bitcount) {
|
||||
mask_addr((unsigned char *) &u, ap->addr_bytecount, prefix_len);
|
||||
buf = vstring_alloc(ap->addr_strlen + ap->slashdigs_strlen);
|
||||
} else {
|
||||
buf = vstring_alloc(ap->addr_strlen);
|
||||
}
|
||||
if (inet_ntop(af, &u, vstring_str(buf), vstring_avail(buf)) == 0)
|
||||
msg_fatal("%s: inet_ntop: %m", myname);
|
||||
vstring_set_payload_size(buf, strlen(vstring_str(buf)));
|
||||
if (prefix_len < ap->addr_bitcount)
|
||||
vstring_sprintf_append(buf, "/%d", prefix_len);
|
||||
return (vstring_export(buf));
|
||||
}
|
27
postfix/src/util/net_mask_top.h
Normal file
27
postfix/src/util/net_mask_top.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef _NET_MASK_TOP_H_INCLUDED_
|
||||
#define _NET_MASK_TOP_H_INCLUDED_
|
||||
|
||||
/*++
|
||||
/* NAME
|
||||
/* net_mask_top 3h
|
||||
/* SUMMARY
|
||||
/* convert net/mask to printable string
|
||||
/* SYNOPSIS
|
||||
/* #include <net_mask_top.h>
|
||||
/* DESCRIPTION
|
||||
/* .nf
|
||||
|
||||
/*
|
||||
* External interface.
|
||||
*/
|
||||
extern char *net_mask_top(int, const void *, int);
|
||||
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/*--*/
|
||||
|
||||
#endif
|
@ -28,6 +28,7 @@
|
||||
/* struct sockaddr *SOCK_ADDR_PTR(ptr)
|
||||
/* unsigned char SOCK_ADDR_FAMILY(ptr)
|
||||
/* unsigned char SOCK_ADDR_LEN(ptr)
|
||||
/* void *SOCK_ADDR_ADDRP(ptr)
|
||||
/* unsigned short SOCK_ADDR_PORT(ptr)
|
||||
/* unsigned short *SOCK_ADDR_PORTP(ptr)
|
||||
/*
|
||||
@ -68,7 +69,8 @@
|
||||
/* address family and length of the real structure that hides
|
||||
/* inside a generic sockaddr structure. On systems where struct
|
||||
/* sockaddr has no sa_len member, SOCK_ADDR_LEN() cannot be
|
||||
/* used as lvalue. SOCK_ADDR_PORT() returns the IPv4 or IPv6
|
||||
/* used as lvalue. SOCKADDR_ADDRP() returns a pointer to the
|
||||
/* IPv4 or IPv6 address. SOCK_ADDR_PORT() returns the IPv4 or IPv6
|
||||
/* port number, in network byte order; it must not be used as
|
||||
/* lvalue. SOCK_ADDR_PORTP() returns a pointer to the same.
|
||||
/*
|
||||
|
@ -45,6 +45,9 @@ extern int sock_addr_in_loopback(const struct sockaddr *);
|
||||
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
|
||||
#endif
|
||||
|
||||
#define SOCK_ADDR_ADDRP(sa) \
|
||||
(SOCK_ADDR_FAMILY(sa) == AF_INET ? \
|
||||
(void *) &SOCK_ADDR_IN_ADDR(sa) : (void *) &SOCK_ADDR_IN6_ADDR(sa))
|
||||
#define SOCK_ADDR_PORT(sa) \
|
||||
(SOCK_ADDR_PTR(sa)->sa_family == AF_INET6 ? \
|
||||
SOCK_ADDR_IN6_PORT(sa) : SOCK_ADDR_IN_PORT(sa))
|
||||
@ -78,8 +81,9 @@ extern int sock_addr_in_loopback(const struct sockaddr *);
|
||||
#define SOCK_ADDR_LEN(sa) sizeof(struct sockaddr_in)
|
||||
#endif
|
||||
|
||||
#define SOCK_ADDR_PORT(sa) SOCK_ADDR_IN_PORT(sa))
|
||||
#define SOCK_ADDR_PORTP(sa) &SOCK_ADDR_IN_PORT(sa))
|
||||
#define SOCK_ADDR_ADDRP(sa) (&SOCK_ADDR_IN_ADDR(sa))
|
||||
#define SOCK_ADDR_PORT(sa) SOCK_ADDR_IN_PORT(sa)
|
||||
#define SOCK_ADDR_PORTP(sa) (&SOCK_ADDR_IN_PORT(sa))
|
||||
|
||||
#define SOCK_ADDR_EQ_ADDR(sa, sb) \
|
||||
(SOCK_ADDR_FAMILY(sa) == AF_INET && SOCK_ADDR_FAMILY(sb) == AF_INET \
|
||||
|
Loading…
x
Reference in New Issue
Block a user