static void smtpd_peer_from_proxy(SMTPD_STATE *state) { typedef struct { const char *name; int (*endpt_lookup) (SMTPD_STATE *); } SMTPD_ENDPT_LOOKUP_INFO; static const SMTPD_ENDPT_LOOKUP_INFO smtpd_endpt_lookup_info[] = { HAPROXY_PROTO_NAME, smtpd_peer_from_haproxy, 0, }; const SMTPD_ENDPT_LOOKUP_INFO *pp; /* * When the proxy information is unavailable, we can't maintain an audit * trail or enforce access control, therefore we forcibly hang up. */ for (pp = smtpd_endpt_lookup_info; /* see below */ ; pp++) { if (pp->name == 0) msg_fatal("unsupported %s value: %s", VAR_SMTPD_UPROXY_PROTO, var_smtpd_uproxy_proto); if (strcmp(var_smtpd_uproxy_proto, pp->name) == 0) break; } if (pp->endpt_lookup(state) < 0) { smtpd_peer_no_client(state); state->flags |= SMTPD_FLAG_HANGUP; } else { smtpd_peer_hostaddr_to_sockaddr(state); } }
static void smtpd_peer_from_default(SMTPD_STATE *state) { /* * The "no client" routine provides surrogate information so that the * application can produce sensible logging when a client disconnects * before the server wakes up. The "not inet" routine provides surrogate * state for (presumably) local IPC channels. */ state->sockaddr_len = sizeof(state->sockaddr); state->dest_sockaddr_len = sizeof(state->dest_sockaddr); if (getpeername(vstream_fileno(state->client), (struct sockaddr *) &state->sockaddr, &state->sockaddr_len) <0 || getsockname(vstream_fileno(state->client), (struct sockaddr *) &state->dest_sockaddr, &state->dest_sockaddr_len) < 0) { if (errno == ENOTSOCK) smtpd_peer_not_inet(state); else smtpd_peer_no_client(state); } else { if (smtpd_peer_sockaddr_to_hostaddr(state) < 0) smtpd_peer_not_inet(state); } }