sync with OpenBSD -current

This commit is contained in:
purplerain 2024-05-07 21:04:28 +00:00
parent a6677bfd36
commit 223def2739
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
29 changed files with 687 additions and 529 deletions

View File

@ -1448,7 +1448,6 @@
./usr/include/ufs/ffs
./usr/include/ufs/ffs/ffs_extern.h
./usr/include/ufs/ffs/fs.h
./usr/include/ufs/ffs/softdep.h
./usr/include/ufs/mfs
./usr/include/ufs/mfs/mfs_extern.h
./usr/include/ufs/mfs/mfsnode.h

View File

@ -2370,6 +2370,7 @@
./usr/share/man/man7/script.7
./usr/share/man/man7/securelevel.7
./usr/share/man/man7/smtpd-filters.7
./usr/share/man/man7/smtpd-tables.7
./usr/share/man/man7/sndio.7
./usr/share/man/man7/symlink.7
./usr/share/man/man7/tbl.7

View File

@ -1,4 +1,4 @@
/* $OpenBSD: lhash.c,v 1.24 2024/05/06 14:38:20 jsing Exp $ */
/* $OpenBSD: lhash.c,v 1.25 2024/05/07 13:40:42 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -110,9 +110,124 @@
#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
static void expand(_LHASH *lh);
static void contract(_LHASH *lh);
static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
static void
expand(_LHASH *lh)
{
LHASH_NODE **n, **n1, **n2, *np;
unsigned int p, i, j;
unsigned long hash, nni;
lh->num_nodes++;
lh->num_expands++;
p = (int)lh->p++;
n1 = &(lh->b[p]);
n2 = &(lh->b[p + (int)lh->pmax]);
*n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */
nni = lh->num_alloc_nodes;
for (np = *n1; np != NULL; ) {
#ifndef OPENSSL_NO_HASH_COMP
hash = np->hash;
#else
hash = lh->hash(np->data);
lh->num_hash_calls++;
#endif
if ((hash % nni) != p) { /* move it */
*n1 = (*n1)->next;
np->next= *n2;
*n2 = np;
} else
n1 = &((*n1)->next);
np= *n1;
}
if ((lh->p) >= lh->pmax) {
j = (int)lh->num_alloc_nodes * 2;
n = reallocarray(lh->b, j, sizeof(LHASH_NODE *));
if (n == NULL) {
/* fputs("realloc error in lhash", stderr); */
lh->error++;
lh->p = 0;
return;
}
/* else */
for (i = (int)lh->num_alloc_nodes; i < j; i++)/* 26/02/92 eay */
n[i] = NULL; /* 02/03/92 eay */
lh->pmax = lh->num_alloc_nodes;
lh->num_alloc_nodes = j;
lh->num_expand_reallocs++;
lh->p = 0;
lh->b = n;
}
}
static void
contract(_LHASH *lh)
{
LHASH_NODE **n, *n1, *np;
np = lh->b[lh->p + lh->pmax - 1];
lh->b[lh->p+lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
if (lh->p == 0) {
n = reallocarray(lh->b, lh->pmax, sizeof(LHASH_NODE *));
if (n == NULL) {
/* fputs("realloc error in lhash", stderr); */
lh->error++;
return;
}
lh->num_contract_reallocs++;
lh->num_alloc_nodes /= 2;
lh->pmax /= 2;
lh->p = lh->pmax - 1;
lh->b = n;
} else
lh->p--;
lh->num_nodes--;
lh->num_contracts++;
n1 = lh->b[(int)lh->p];
if (n1 == NULL)
lh->b[(int)lh->p] = np;
else {
while (n1->next != NULL)
n1 = n1->next;
n1->next = np;
}
}
static LHASH_NODE **
getrn(_LHASH *lh, const void *data, unsigned long *rhash)
{
LHASH_NODE **ret, *n1;
unsigned long hash, nn;
LHASH_COMP_FN_TYPE cf;
hash = (*(lh->hash))(data);
lh->num_hash_calls++;
*rhash = hash;
nn = hash % lh->pmax;
if (nn < lh->p)
nn = hash % lh->num_alloc_nodes;
cf = lh->comp;
ret = &(lh->b[(int)nn]);
for (n1 = *ret; n1 != NULL; n1 = n1->next) {
#ifndef OPENSSL_NO_HASH_COMP
lh->num_hash_comps++;
if (n1->hash != hash) {
ret = &(n1->next);
continue;
}
#endif
lh->num_comp_calls++;
if (cf(n1->data, data) == 0)
break;
ret = &(n1->next);
}
return (ret);
}
_LHASH *
lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
@ -313,125 +428,6 @@ lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
}
LCRYPTO_ALIAS(lh_doall_arg);
static void
expand(_LHASH *lh)
{
LHASH_NODE **n, **n1, **n2, *np;
unsigned int p, i, j;
unsigned long hash, nni;
lh->num_nodes++;
lh->num_expands++;
p = (int)lh->p++;
n1 = &(lh->b[p]);
n2 = &(lh->b[p + (int)lh->pmax]);
*n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */
nni = lh->num_alloc_nodes;
for (np = *n1; np != NULL; ) {
#ifndef OPENSSL_NO_HASH_COMP
hash = np->hash;
#else
hash = lh->hash(np->data);
lh->num_hash_calls++;
#endif
if ((hash % nni) != p) { /* move it */
*n1 = (*n1)->next;
np->next= *n2;
*n2 = np;
} else
n1 = &((*n1)->next);
np= *n1;
}
if ((lh->p) >= lh->pmax) {
j = (int)lh->num_alloc_nodes * 2;
n = reallocarray(lh->b, j, sizeof(LHASH_NODE *));
if (n == NULL) {
/* fputs("realloc error in lhash", stderr); */
lh->error++;
lh->p = 0;
return;
}
/* else */
for (i = (int)lh->num_alloc_nodes; i < j; i++)/* 26/02/92 eay */
n[i] = NULL; /* 02/03/92 eay */
lh->pmax = lh->num_alloc_nodes;
lh->num_alloc_nodes = j;
lh->num_expand_reallocs++;
lh->p = 0;
lh->b = n;
}
}
static void
contract(_LHASH *lh)
{
LHASH_NODE **n, *n1, *np;
np = lh->b[lh->p + lh->pmax - 1];
lh->b[lh->p+lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
if (lh->p == 0) {
n = reallocarray(lh->b, lh->pmax, sizeof(LHASH_NODE *));
if (n == NULL) {
/* fputs("realloc error in lhash", stderr); */
lh->error++;
return;
}
lh->num_contract_reallocs++;
lh->num_alloc_nodes /= 2;
lh->pmax /= 2;
lh->p = lh->pmax - 1;
lh->b = n;
} else
lh->p--;
lh->num_nodes--;
lh->num_contracts++;
n1 = lh->b[(int)lh->p];
if (n1 == NULL)
lh->b[(int)lh->p] = np;
else {
while (n1->next != NULL)
n1 = n1->next;
n1->next = np;
}
}
static LHASH_NODE **
getrn(_LHASH *lh, const void *data, unsigned long *rhash)
{
LHASH_NODE **ret, *n1;
unsigned long hash, nn;
LHASH_COMP_FN_TYPE cf;
hash = (*(lh->hash))(data);
lh->num_hash_calls++;
*rhash = hash;
nn = hash % lh->pmax;
if (nn < lh->p)
nn = hash % lh->num_alloc_nodes;
cf = lh->comp;
ret = &(lh->b[(int)nn]);
for (n1 = *ret; n1 != NULL; n1 = n1->next) {
#ifndef OPENSSL_NO_HASH_COMP
lh->num_hash_comps++;
if (n1->hash != hash) {
ret = &(n1->next);
continue;
}
#endif
lh->num_comp_calls++;
if (cf(n1->data, data) == 0)
break;
ret = &(n1->next);
}
return (ret);
}
/* The following hash seems to work very well on normal text strings
* no collisions on /usr/dict/words and it distributes on %2^n quite
* well, not as good as MD5, but still good.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: endian.h,v 1.7 2018/10/02 21:30:44 naddy Exp $ */
/* $OpenBSD: endian.h,v 1.8 2024/05/07 14:26:48 naddy Exp $ */
/*-
* Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
@ -27,34 +27,6 @@
#ifndef _MACHINE_ENDIAN_H_
#define _MACHINE_ENDIAN_H_
#ifndef __FROM_SYS__ENDIAN
#include <sys/_types.h>
#endif
static __inline __uint16_t
__swap16md(__uint16_t _x)
{
__asm ("rorw $8, %w0" : "+r" (_x));
return (_x);
}
static __inline __uint32_t
__swap32md(__uint32_t _x)
{
__asm ("bswap %0" : "+r" (_x));
return (_x);
}
static __inline __uint64_t
__swap64md(__uint64_t _x)
{
__asm ("bswapq %0" : "+r" (_x));
return (_x);
}
/* Tell sys/endian.h we have MD variants of the swap macros. */
#define __HAVE_MD_SWAP
#define _BYTE_ORDER _LITTLE_ENDIAN
#ifndef __FROM_SYS__ENDIAN

View File

@ -1,4 +1,4 @@
/* $OpenBSD: endian.h,v 1.11 2018/10/02 21:30:44 naddy Exp $ */
/* $OpenBSD: endian.h,v 1.12 2024/05/07 14:26:48 naddy Exp $ */
/*
* Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@ -19,48 +19,11 @@
#ifndef _ARM_ENDIAN_H_
#define _ARM_ENDIAN_H_
#ifndef __FROM_SYS__ENDIAN
#include <sys/_types.h>
#endif
static __inline __uint16_t
__swap16md(__uint16_t _x)
{
__uint16_t _rv;
__asm ("rev16 %0, %1" : "=r" (_rv) : "r" (_x));
return (_rv);
}
static __inline __uint32_t
__swap32md(__uint32_t _x)
{
__uint32_t _rv;
__asm ("rev %0, %1" : "=r" (_rv) : "r" (_x));
return (_rv);
}
static __inline __uint64_t
__swap64md(__uint64_t _x)
{
__uint64_t _rv;
_rv = (__uint64_t)__swap32md(_x >> 32) |
(__uint64_t)__swap32md(_x) << 32;
return (_rv);
}
/* Tell sys/endian.h we have MD variants of the swap macros. */
#define __HAVE_MD_SWAP
#define _BYTE_ORDER _LITTLE_ENDIAN
#define __STRICT_ALIGNMENT
#ifndef __FROM_SYS__ENDIAN
#include <sys/endian.h>
#endif
#endif /* _ARM_ENDIAN_H_ */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: endian.h,v 1.3 2018/10/01 17:42:16 naddy Exp $ */
/* $OpenBSD: endian.h,v 1.4 2024/05/07 14:26:48 naddy Exp $ */
/*
* Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@ -19,48 +19,11 @@
#ifndef _MACHINE_ENDIAN_H_
#define _MACHINE_ENDIAN_H_
#ifndef __FROM_SYS__ENDIAN
#include <sys/_types.h>
#endif
static __inline __uint16_t
__swap16md(__uint16_t _x)
{
__uint16_t _rv;
__asm ("rev16 %w0, %w1" : "=r" (_rv) : "r"(_x));
return (_rv);
}
static __inline __uint32_t
__swap32md(__uint32_t _x)
{
__uint32_t _rv;
__asm ("rev %w0, %w1" : "=r" (_rv) : "r"(_x));
return (_rv);
}
static __inline __uint64_t
__swap64md(__uint64_t _x)
{
__uint64_t _rv;
__asm ("rev %x0, %x1" : "=r" (_rv) : "r"(_x));
return (_rv);
}
/* Tell sys/endian.h we have MD variants of the swap macros. */
#define __HAVE_MD_SWAP
#define _BYTE_ORDER _LITTLE_ENDIAN
#define __STRICT_ALIGNMENT
#ifndef __FROM_SYS__ENDIAN
#include <sys/endian.h>
#endif
#endif /* _MACHINE_ENDIAN_H_ */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: endian.h,v 1.19 2018/10/02 21:30:44 naddy Exp $ */
/* $OpenBSD: endian.h,v 1.20 2024/05/07 14:26:48 naddy Exp $ */
/*-
* Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
@ -27,34 +27,6 @@
#ifndef _MACHINE_ENDIAN_H_
#define _MACHINE_ENDIAN_H_
#ifndef __FROM_SYS__ENDIAN
#include <sys/_types.h>
#endif
static __inline __uint16_t
__swap16md(__uint16_t _x)
{
__asm ("rorw $8, %w0" : "+r" (_x));
return (_x);
}
static __inline __uint32_t
__swap32md(__uint32_t _x)
{
__asm ("bswap %0" : "+r" (_x));
return (_x);
}
static __inline __uint64_t
__swap64md(__uint64_t _x)
{
return ((__uint64_t)__swap32md(_x >> 32) |
(__uint64_t)__swap32md(_x & 0xffffffff) << 32);
}
/* Tell sys/endian.h we have MD variants of the swap macros. */
#define __HAVE_MD_SWAP
#define _BYTE_ORDER _LITTLE_ENDIAN
#ifndef __FROM_SYS__ENDIAN

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_bnxt.c,v 1.48 2024/04/12 19:27:43 jan Exp $ */
/* $OpenBSD: if_bnxt.c,v 1.49 2024/05/07 18:35:23 jan Exp $ */
/*-
* Broadcom NetXtreme-C/E network driver.
*
@ -1427,7 +1427,7 @@ bnxt_start(struct ifqueue *ifq)
uint32_t paylen;
ether_extract_headers(m, &ext);
if (ext.tcp) {
if (ext.tcp && m->m_pkthdr.ph_mss > 0) {
lflags |= TX_BD_LONG_LFLAGS_LSO;
hdrsize = sizeof(*ext.eh);
if (ext.ip4 || ext.ip6)

View File

@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/* $OpenBSD: if_em.c,v 1.374 2024/02/16 22:30:54 mglocker Exp $ */
/* $OpenBSD: if_em.c,v 1.375 2024/05/07 18:35:23 jan Exp $ */
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
#include <dev/pci/if_em.h>
@ -2452,7 +2452,7 @@ em_tso_setup(struct em_queue *que, struct mbuf *mp, u_int head,
#endif
ether_extract_headers(mp, &ext);
if (ext.tcp == NULL)
if (ext.tcp == NULL || mp->m_pkthdr.ph_mss == 0)
goto out;
vlan_macip_lens |= (sizeof(*ext.eh) << E1000_ADVTXD_MACLEN_SHIFT);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_igc.c,v 1.22 2024/05/06 04:25:52 dlg Exp $ */
/* $OpenBSD: if_igc.c,v 1.23 2024/05/07 18:35:23 jan Exp $ */
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
@ -2093,7 +2093,7 @@ igc_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, int prod,
}
if (ISSET(mp->m_pkthdr.csum_flags, M_TCP_TSO)) {
if (ext.tcp) {
if (ext.tcp && mp->m_pkthdr.ph_mss > 0) {
uint32_t hdrlen, thlen, paylen, outlen;
thlen = ext.tcphlen;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_ix.c,v 1.212 2024/05/01 10:43:42 jan Exp $ */
/* $OpenBSD: if_ix.c,v 1.213 2024/05/07 18:35:23 jan Exp $ */
/******************************************************************************
@ -2535,7 +2535,7 @@ ixgbe_tx_offload(struct mbuf *mp, uint32_t *vlan_macip_lens,
}
if (mp->m_pkthdr.csum_flags & M_TCP_TSO) {
if (ext.tcp) {
if (ext.tcp && mp->m_pkthdr.ph_mss > 0) {
uint32_t hdrlen, thlen, paylen, outlen;
thlen = ext.tcphlen;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_ixl.c,v 1.98 2024/04/12 19:27:43 jan Exp $ */
/* $OpenBSD: if_ixl.c,v 1.99 2024/05/07 18:35:23 jan Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@ -2848,7 +2848,7 @@ ixl_tx_setup_offload(struct mbuf *m0, struct ixl_tx_ring *txr,
}
if (ISSET(m0->m_pkthdr.csum_flags, M_TCP_TSO)) {
if (ext.tcp) {
if (ext.tcp && m0->m_pkthdr.ph_mss > 0) {
struct ixl_tx_desc *ring, *txd;
uint64_t cmd = 0, paylen, outlen;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_vmx.c,v 1.83 2024/04/02 20:59:48 jan Exp $ */
/* $OpenBSD: if_vmx.c,v 1.84 2024/05/07 18:35:23 jan Exp $ */
/*
* Copyright (c) 2013 Tsubai Masanari
@ -1463,7 +1463,7 @@ vmxnet3_tx_offload(struct vmxnet3_txdesc *sop, struct mbuf *m)
* TCP Segmentation Offload
*/
if (ext.tcp == NULL) {
if (ext.tcp == NULL || m->m_pkthdr.ph_mss == 0) {
tcpstat_inc(tcps_outbadtso);
return;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_vio.c,v 1.32 2024/04/10 19:55:50 jan Exp $ */
/* $OpenBSD: if_vio.c,v 1.33 2024/05/07 18:35:23 jan Exp $ */
/*
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
@ -777,7 +777,7 @@ vio_tx_offload(struct virtio_net_hdr *hdr, struct mbuf *m)
if (!ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO))
return;
if (!ext.tcp) {
if (!ext.tcp || m->m_pkthdr.ph_mss == 0) {
tcpstat_inc(tcps_outbadtso);
return;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kern_sig.c,v 1.325 2024/04/18 09:06:42 claudio Exp $ */
/* $OpenBSD: kern_sig.c,v 1.326 2024/05/07 10:46:35 claudio Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@ -1171,7 +1171,7 @@ ptsignal(struct proc *p, int signum, enum signal_type type)
atomic_clearbits_int(&p->p_flag, P_SUSPSIG);
wakeparent = 1;
if (action == SIG_DFL)
atomic_clearbits_int(siglist, mask);
mask = 0;
if (action == SIG_CATCH)
goto runfast;
if (p->p_wchan == NULL)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket2.c,v 1.153 2024/05/03 17:43:09 mvs Exp $ */
/* $OpenBSD: uipc_socket2.c,v 1.154 2024/05/07 15:54:23 claudio Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
@ -552,7 +552,10 @@ sblock(struct socket *so, struct sockbuf *sb, int flags)
if (!(flags & SBL_WAIT))
rwflags |= RW_NOSLEEP;
return rw_enter(&sb->sb_lock, rwflags);
error = rw_enter(&sb->sb_lock, rwflags);
if (error == EBUSY)
error = EWOULDBLOCK;
return error;
}
soassertlocked(so);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: fuse_vfsops.c,v 1.45 2021/05/01 16:18:29 gnezdo Exp $ */
/* $OpenBSD: fuse_vfsops.c,v 1.46 2024/05/07 14:27:11 mvs Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@ -114,7 +114,8 @@ fusefs_mount(struct mount *mp, const char *path, void *data,
fmp->allow_other = args->allow_other;
mp->mnt_data = fmp;
mp->mnt_flag |= MNT_LOCAL;
/* FUSE file system is not truly local. */
mp->mnt_flag &= ~MNT_LOCAL;
vfs_getnewfsid(mp);
memset(mp->mnt_stat.f_mntonname, 0, MNAMELEN);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.156 2024/04/30 15:40:43 tobias Exp $ */
/* $OpenBSD: ssh-keyscan.c,v 1.157 2024/05/06 19:26:17 tobias Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -96,19 +96,13 @@ typedef struct Connection {
u_char c_status; /* State of connection on this file desc. */
#define CS_UNUSED 0 /* File descriptor unused */
#define CS_CON 1 /* Waiting to connect/read greeting */
#define CS_SIZE 2 /* Waiting to read initial packet size */
#define CS_KEYS 3 /* Waiting to read public key packet */
int c_fd; /* Quick lookup: c->c_fd == c - fdcon */
int c_plen; /* Packet length field for ssh packet */
int c_len; /* Total bytes which must be read. */
int c_off; /* Length of data read so far. */
int c_keytype; /* Only one of KT_* */
sig_atomic_t c_done; /* SSH2 done */
char *c_namebase; /* Address to free for c_name and c_namelist */
char *c_name; /* Hostname of connection for errors */
char *c_namelist; /* Pointer to other possible addresses */
char *c_output_name; /* Hostname of connection for output */
char *c_data; /* Data read from this fd */
struct ssh *c_ssh; /* SSH-connection */
struct timespec c_ts; /* Time at which connection gets aborted */
TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */
@ -397,9 +391,6 @@ conalloc(const char *iname, const char *oname, int keytype)
fdcon[s].c_name = name;
fdcon[s].c_namelist = namelist;
fdcon[s].c_output_name = xstrdup(oname);
fdcon[s].c_data = (char *) &fdcon[s].c_plen;
fdcon[s].c_len = 4;
fdcon[s].c_off = 0;
fdcon[s].c_keytype = keytype;
monotime_ts(&fdcon[s].c_ts);
fdcon[s].c_ts.tv_sec += timeout;
@ -417,8 +408,6 @@ confree(int s)
fatal("confree: attempt to free bad fdno %d", s);
free(fdcon[s].c_namebase);
free(fdcon[s].c_output_name);
if (fdcon[s].c_status == CS_KEYS)
free(fdcon[s].c_data);
fdcon[s].c_status = CS_UNUSED;
fdcon[s].c_keytype = 0;
if (fdcon[s].c_ssh) {
@ -433,15 +422,6 @@ confree(int s)
ncon--;
}
static void
contouch(int s)
{
TAILQ_REMOVE(&tq, &fdcon[s], c_link);
monotime_ts(&fdcon[s].c_ts);
fdcon[s].c_ts.tv_sec += timeout;
TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
}
static int
conrecycle(int s)
{
@ -546,35 +526,11 @@ static void
conread(int s)
{
con *c = &fdcon[s];
size_t n;
if (c->c_status == CS_CON) {
congreet(s);
return;
}
n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off);
if (n == 0) {
error("read (%s): %s", c->c_name, strerror(errno));
confree(s);
return;
}
c->c_off += n;
if (c->c_status != CS_CON)
fatal("conread: invalid status %d", c->c_status);
if (c->c_off == c->c_len)
switch (c->c_status) {
case CS_SIZE:
c->c_plen = htonl(c->c_plen);
c->c_len = c->c_plen + 8 - (c->c_plen & 7);
c->c_off = 0;
c->c_data = xmalloc(c->c_len);
c->c_status = CS_KEYS;
break;
default:
fatal("conread: invalid status %d", c->c_status);
break;
}
contouch(s);
congreet(s);
}
static void

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tty.c,v 1.13 2022/12/04 23:50:50 cheloha Exp $ */
/* $OpenBSD: tty.c,v 1.14 2024/05/06 16:49:46 cheloha Exp $ */
/* $NetBSD: tty.c,v 1.4 1994/12/07 00:46:57 jtc Exp $ */
/*
@ -57,9 +57,9 @@ main(int argc, char *argv[])
}
if (unveil(_PATH_DEVDB, "r") == -1)
err(1, "unveil %s", _PATH_DEVDB);
err(2, "unveil %s", _PATH_DEVDB);
if (pledge("stdio rpath", NULL) == -1)
err(1, "pledge");
err(2, "pledge");
t = ttyname(STDIN_FILENO);
if (!sflag)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dkstats.c,v 1.41 2019/06/28 13:35:05 deraadt Exp $ */
/* $OpenBSD: dkstats.c,v 1.42 2024/05/06 16:54:22 cheloha Exp $ */
/* $NetBSD: dkstats.c,v 1.1 1996/05/10 23:19:27 thorpej Exp $ */
/*
@ -101,11 +101,6 @@ int dk_ndrive = 0;
int *dk_select;
char **dr_name;
/* Missing from <sys/time.h> */
#define timerset(tvp, uvp) \
((uvp)->tv_sec = (tvp)->tv_sec); \
((uvp)->tv_usec = (tvp)->tv_usec)
#define SWAP(fld) tmp = cur.fld; \
cur.fld -= last.fld; \
last.fld = tmp
@ -135,11 +130,9 @@ dkswap(void)
SWAP(dk_wbytes[i]);
/* Delta Time. */
timerclear(&tmp_timer);
timerset(&(cur.dk_time[i]), &tmp_timer);
timersub(&tmp_timer, &(last.dk_time[i]), &(cur.dk_time[i]));
timerclear(&(last.dk_time[i]));
timerset(&tmp_timer, &(last.dk_time[i]));
tmp_timer = cur.dk_time[i];
timersub(&tmp_timer, &last.dk_time[i], &cur.dk_time[i]);
last.dk_time[i] = tmp_timer;
}
for (i = 0; i < CPUSTATES; i++) {
long ltmp;
@ -370,7 +363,7 @@ dkreadstats(void)
cur.dk_seek[i] = q[i].ds_seek;
cur.dk_rbytes[i] = q[i].ds_rbytes;
cur.dk_wbytes[i] = q[i].ds_wbytes;
timerset(&(q[i].ds_time), &(cur.dk_time[i]));
cur.dk_time[i] = q[i].ds_time;
}
free(q);
@ -408,7 +401,7 @@ dkreadstats(void)
cur.dk_seek[i] = cur_disk.dk_seek;
cur.dk_rbytes[i] = cur_disk.dk_rbytes;
cur.dk_wbytes[i] = cur_disk.dk_wbytes;
timerset(&(cur_disk.dk_time), &(cur.dk_time[i]));
cur.dk_time[i] = cur_disk.dk_time;
p = TAILQ_NEXT(&cur_disk, dk_link);
}
deref_nl(X_CP_TIME, cur.cp_time, sizeof(cur.cp_time));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: makemap.c,v 1.76 2024/02/11 09:24:26 op Exp $ */
/* $OpenBSD: makemap.c,v 1.77 2024/05/07 12:10:06 op Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@ -57,7 +57,8 @@ enum output_type {
* Stub functions so that makemap compiles using minimum object files.
*/
int
fork_proc_backend(const char *backend, const char *conf, const char *procname)
fork_proc_backend(const char *backend, const char *conf, const char *procname,
int do_stdout)
{
return (-1);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: queue_proc.c,v 1.10 2024/01/20 09:01:03 claudio Exp $ */
/* $OpenBSD: queue_proc.c,v 1.11 2024/05/07 12:10:06 op Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@ -287,7 +287,7 @@ queue_proc_init(struct passwd *pw, int server, const char *conf)
uint32_t version;
int fd;
fd = fork_proc_backend("queue", conf, "queue-proc");
fd = fork_proc_backend("queue", conf, "queue-proc", 0);
if (fd == -1)
fatalx("queue-proc: exiting");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: scheduler_proc.c,v 1.9 2021/06/14 17:58:16 eric Exp $ */
/* $OpenBSD: scheduler_proc.c,v 1.10 2024/05/07 12:10:06 op Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@ -100,7 +100,7 @@ scheduler_proc_init(const char *conf)
int fd, r;
uint32_t version;
fd = fork_proc_backend("scheduler", conf, "scheduler-proc");
fd = fork_proc_backend("scheduler", conf, "scheduler-proc", 0);
if (fd == -1)
fatalx("scheduler-proc: exiting");

View File

@ -0,0 +1,272 @@
.\" $OpenBSD: smtpd-tables.7,v 1.1 2024/05/07 12:13:43 op Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
.\" Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
.\" Copyright (c) 2024 Omar Polo <op@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\"
.Dd $Mdocdate: May 7 2024 $
.Dt SMTPD-TABLES 7
.Os
.Sh NAME
.Nm smtpd-tables
.Nd table API for the smtpd daemon
.Sh DESCRIPTION
The
.Xr smtpd 8
daemon provides a Simple Mail Transfer Protocol (SMTPD) implementation,
which allows ordinary machines to become Mail eXchangers (MX).
Some features that are commonly used by MX,
such as querying databases for user credentials,
are outside of the scope of SMTP and too complex to fit in
.Xr smtpd 8 .
.Pp
Because an MX may need to provide these features,
.Xr smtpd 8
provides an API to implement
.Xr table 5
backends with a simple text-based protocol.
.Sh DESIGN
.Nm
are programs that run as unique standalone processes,
they do not share
.Xr smtpd 8
address space.
They are executed by
.Xr smtpd 8
at startup and expected to run in an infinite loop,
reading events and queries from standard input and
writing responses to standard output.
They are not allowed to terminate.
.Pp
Because
.Nm
are standalone programs that communicate with
.Xr smtpd 8 ,
they may run as different users than
.Xr smtpd 8
and may be written in any language.
.Nm
must not use blocking I/O,
they must support answering asynchronously to
.Xr smtpd 8 .
.Sh PROTOCOL
The protocol consist of human-readable lines exchanged between
.Nm
and
.Xr smtpd 8 .
.Pp
The protocol begins with a handshake.
First,
.Xr smtpd 8
provides
.Nm
with general configuration information in the form of
key-value lines, terminated by
.Ql config|ready .
For example:
.Bd -literal -offset indent
config|smtpd-version|7.5.0
config|protocol|0.1
config|tablename|devs
config|ready
.Ed
.Pp
Then,
.Nm
register the supported services, terminating with
.Ql register|ready .
For example:
.Bd -literal -offset indent
register|alias
register|credentials
register|ready
.Ed
.Pp
Finally,
.Xr smtpd 8
can start querying the table.
For example:
.Bd -literal -offset indent
table|0.1|1713795082.354255|devs|lookup|alias|b72508d|op
.Ed
.Pp
The
.Dq |
character is used to separate the fields and may only appear
verbatim in the last field of the payload, in which case it
should be considered a regular character and not a separator.
No other field may contain a
.Dq | .
.Pp
Each request has a common set of fields, followed by some
other fields that are operation-specific.
The common format consists of a protocol prefix
.Sq table ,
the protocol version, the timestamp and the table name.
For example:
.Bd -literal -offset indent
table|0.1|1713795091.202157|devs
.Ed
.Pp
The protocol is inherently asynchronous, so multiple request
may be sent without waiting for the table to reply.
All the replies have a common prefix, followed by the
operation-specific response.
The common format consist of a prefix with the operation name
in followed by
.Sq -result ,
and the unique ID of the request.
For example:
.Bd -literal -offset indent
lookup-result|b72508d
.Ed
.Pp
The list of operations, operation-specific parameters and
responses are as follows:
.Bl -tag -width Ds
.It Cm update Ar id
Ask the table to reload its configuration.
The result is either
.Sq ok
on success or
.Sq error
upon a failure to do so.
.It Cm check Ar service id query
Check whether
.Ar query
is present in the table.
The result is
.Sq found
if found,
.Sq not-found
if not, or
.Sq error
upon an error.
.It Cm lookup Ar service id query
Look up a value in the table for given the
.Ar query .
The result is
.Sq found
and the value if found,
.Sq not-found
if not found, or
.Sq error
upon an error.
.It Cm fetch Ar service id
Fetch the next item from the table.
It is only supported for the
.Ic source
and
.Ic relayhost
services.
The result is
.Sq found
and the value if found,
.Sq not-found
if not found, or
.Sq error
upon an error.
.El
.Pp
Each service has a specific format for the result.
The exact syntax for the values and eventually the keys are
described in
.Xr table 5 .
The services and their result format are as follows:
.Pp
.Bl -tag -width mailaddrmap -compact
.It Ic alias
One or more aliases separated by a comma.
.It Ic domain
A domain name.
.\" XXX are wildcards allowed?
.It Ic credentials
The user name, followed by
.Sq \&:
and the encrypted password as per
.Xr smtpctl 8
.Cm encrypt
subcommand.
.It Ic netaddr
IPv4 and IPv6 address or netmask.
.It Ic userinfo
The user id, followed by
.Sq \&:
then the group id, then
.Sq \&:
and finally the home directory.
.It Ic source
IPv4 and IPv6 address.
.It Ic mailaddr
An username, a domain or a full email address.
.It Ic addrname
Used to map IP addresses to hostnames.
.\" .It Ic mailaddrmap
.\" XXX missing K_RELAYHOST, K_STRING and K_REGEX
.El
.Sh EXAMPLES
Assuming the table is called
.Dq devs ,
here's an example of a successful
.Cm update
transaction:
.Bd -literal -offset indent
table|0.1|1713795097.394049|devs|update|478ff0d2
update-result|478ff0d2|ok
.Ed
.Pp
A
.Cm check
request for the
.Ic netaddr
service for the 192.168.0.7 IPv4 address which is
not in the table:
.Bd -literal -offset indent
table|0.1|1713795103.314423|devs|check|netaddr|e5862859|192.168.0.7
check-result|e5862859|not-found
.Ed
.Pp
A successful
.Cm lookup
request for the
.Ic userinfo
service for the user
.Sq op :
.Bd -literal -offset indent
table|0.1|1713795110.354921|devs|lookup|userinfo|f993c74|op
lookup-result|f993c74|found|1000:1000:/home/op
.Ed
.Pp
A series of
.Cm fetch
requests for the
.Cm source
service:
.Bd -literal -offset indent
table|0.1|1713795116.227321|devs|fetch|source|189bd3ee
lookup-result|189bd3ee|found|192.168.1.7
table|0.1|1713795120.162438|devs|fetch|source|9e4c56d4
lookup-result|9e4c56d4|found|10.0.0.8
table|0.1|1713795122.930928|devs|fetch|source|f2c8b906
lookup-result|f2c8b906|not-found
.Ed
.Sh SEE ALSO
.Xr smtpd 8
.Sh HISTORY
.Nm
first appeared in
.Ox 7.6 .

View File

@ -1,4 +1,4 @@
/* $OpenBSD: smtpd.c,v 1.350 2024/04/24 21:31:31 op Exp $ */
/* $OpenBSD: smtpd.c,v 1.351 2024/05/07 12:10:06 op Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@ -1127,7 +1127,8 @@ load_pki_keys(void)
}
int
fork_proc_backend(const char *key, const char *conf, const char *procname)
fork_proc_backend(const char *key, const char *conf, const char *procname,
int do_stdout)
{
pid_t pid;
int sp[2];
@ -1165,6 +1166,8 @@ fork_proc_backend(const char *key, const char *conf, const char *procname)
if (pid == 0) {
/* child process */
dup2(sp[0], STDIN_FILENO);
if (do_stdout)
dup2(sp[0], STDOUT_FILENO);
if (closefrom(STDERR_FILENO + 1) == -1)
exit(1);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: smtpd.h,v 1.683 2024/03/02 22:40:28 op Exp $ */
/* $OpenBSD: smtpd.h,v 1.684 2024/05/07 12:10:06 op Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@ -1620,7 +1620,7 @@ const char *proc_name(enum smtp_proc_type);
const char *proc_title(enum smtp_proc_type);
const char *imsg_to_str(int);
void log_imsg(int, int, struct imsg *);
int fork_proc_backend(const char *, const char *, const char *);
int fork_proc_backend(const char *, const char *, const char *, int);
/* srs.c */
@ -1640,6 +1640,8 @@ struct stat_value *stat_timespec(struct timespec *);
/* table.c */
const char *table_service_name(enum table_service);
int table_service_from_name(const char *);
struct table *table_find(struct smtpd *, const char *);
struct table *table_create(struct smtpd *, const char *, const char *,
const char *);

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.114 2021/11/20 19:11:33 jmc Exp $
# $OpenBSD: Makefile,v 1.115 2024/05/07 09:10:33 op Exp $
.PATH: ${.CURDIR}/..
@ -76,7 +76,9 @@ SRCS+= scheduler_proc.c
SRCS+= stat_ramstat.c
MAN= sendmail.8 smtpd.8 smtpd-filters.7 smtpd.conf.5 table.5
MAN= sendmail.8 smtpd.8 smtpd-filters.7 smtpd-tables.7
MAN+= smtpd.conf.5 table.5
BINDIR= /usr/sbin
LDADD+= -levent -lutil -ltls -lssl -lcrypto -lz

View File

@ -1,4 +1,4 @@
/* $OpenBSD: table.c,v 1.51 2024/01/04 09:34:03 op Exp $ */
/* $OpenBSD: table.c,v 1.52 2024/05/07 12:10:06 op Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@ -37,7 +37,6 @@ extern struct table_backend table_backend_db;
extern struct table_backend table_backend_getpwnam;
extern struct table_backend table_backend_proc;
static const char * table_service_name(enum table_service);
static int table_parse_lookup(enum table_service, const char *, const char *,
union lookup *);
static int parse_sockaddr(struct sockaddr *, int, const char *);
@ -67,27 +66,59 @@ table_backend_lookup(const char *backend)
return NULL;
}
static const char *
const char *
table_service_name(enum table_service s)
{
switch (s) {
case K_NONE: return "NONE";
case K_ALIAS: return "ALIAS";
case K_DOMAIN: return "DOMAIN";
case K_CREDENTIALS: return "CREDENTIALS";
case K_NETADDR: return "NETADDR";
case K_USERINFO: return "USERINFO";
case K_SOURCE: return "SOURCE";
case K_MAILADDR: return "MAILADDR";
case K_ADDRNAME: return "ADDRNAME";
case K_MAILADDRMAP: return "MAILADDRMAP";
case K_RELAYHOST: return "RELAYHOST";
case K_STRING: return "STRING";
case K_REGEX: return "REGEX";
case K_NONE: return "none";
case K_ALIAS: return "alias";
case K_DOMAIN: return "domain";
case K_CREDENTIALS: return "credentials";
case K_NETADDR: return "netaddr";
case K_USERINFO: return "userinfo";
case K_SOURCE: return "source";
case K_MAILADDR: return "mailaddr";
case K_ADDRNAME: return "addrname";
case K_MAILADDRMAP: return "mailaddrmap";
case K_RELAYHOST: return "relayhost";
case K_STRING: return "string";
case K_REGEX: return "regex";
}
return "???";
}
int
table_service_from_name(const char *service)
{
if (!strcmp(service, "none"))
return K_NONE;
if (!strcmp(service, "alias"))
return K_ALIAS;
if (!strcmp(service, "domain"))
return K_DOMAIN;
if (!strcmp(service, "credentials"))
return K_CREDENTIALS;
if (!strcmp(service, "netaddr"))
return K_NETADDR;
if (!strcmp(service, "userinfo"))
return K_USERINFO;
if (!strcmp(service, "source"))
return K_SOURCE;
if (!strcmp(service, "mailaddr"))
return K_MAILADDR;
if (!strcmp(service, "addrname"))
return K_ADDRNAME;
if (!strcmp(service, "mailaddrmap"))
return K_MAILADDRMAP;
if (!strcmp(service, "relayhost"))
return K_RELAYHOST;
if (!strcmp(service, "string"))
return K_STRING;
if (!strcmp(service, "regex"))
return K_REGEX;
return (-1);
}
struct table *
table_find(struct smtpd *conf, const char *name)
{

View File

@ -1,6 +1,7 @@
/* $OpenBSD: table_proc.c,v 1.17 2021/06/14 17:58:16 eric Exp $ */
/* $OpenBSD: table_proc.c,v 1.18 2024/05/07 12:10:06 op Exp $ */
/*
* Copyright (c) 2024 Omar Polo <op@openbsd.org>
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@ -17,87 +18,104 @@
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "smtpd.h"
#include "log.h"
#define PROTOCOL_VERSION "0.1"
struct table_proc_priv {
pid_t pid;
struct imsgbuf ibuf;
FILE *in;
FILE *out;
char *line;
size_t linesize;
/*
* The last ID used in a request. At the moment the protocol
* is synchronous from our point of view, so it's used to
* assert that the table replied with the correct ID.
*/
char lastid[16];
};
static struct imsg imsg;
static size_t rlen;
static char *rdata;
static char *
table_proc_nextid(struct table *table)
{
struct table_proc_priv *priv = table->t_handle;
int r;
extern char **environ;
r = snprintf(priv->lastid, sizeof(priv->lastid), "%lld",
(unsigned long long)arc4random());
if (r < 0 || (size_t)r >= sizeof(priv->lastid))
fatal("table-proc: snprintf");
return (priv->lastid);
}
static void
table_proc_call(struct table_proc_priv *p)
table_proc_send(struct table *table, const char *type, int service,
const char *param)
{
ssize_t n;
struct table_proc_priv *priv = table->t_handle;
struct timeval tv;
if (imsg_flush(&p->ibuf) == -1) {
log_warn("warn: table-proc: imsg_flush");
fatalx("table-proc: exiting");
}
gettimeofday(&tv, NULL);
fprintf(priv->out, "table|%s|%lld.%06ld|%s|%s",
PROTOCOL_VERSION, (long long)tv.tv_sec, (long)tv.tv_usec,
table->t_name, type);
if (service != -1) {
fprintf(priv->out, "|%s|%s", table_service_name(service),
table_proc_nextid(table));
if (param)
fprintf(priv->out, "|%s", param);
fputc('\n', priv->out);
} else
fprintf(priv->out, "|%s\n", table_proc_nextid(table));
while (1) {
if ((n = imsg_get(&p->ibuf, &imsg)) == -1) {
log_warn("warn: table-proc: imsg_get");
break;
}
if (n) {
rlen = imsg.hdr.len - IMSG_HEADER_SIZE;
rdata = imsg.data;
if (fflush(priv->out) == EOF)
fatal("table-proc: fflush");
}
if (imsg.hdr.type != PROC_TABLE_OK) {
log_warnx("warn: table-proc: bad response");
break;
}
return;
}
static const char *
table_proc_recv(struct table *table, const char *type)
{
struct table_proc_priv *priv = table->t_handle;
const char *l;
ssize_t linelen;
size_t len;
if ((n = imsg_read(&p->ibuf)) == -1 && errno != EAGAIN) {
log_warn("warn: table-proc: imsg_read");
break;
}
if ((linelen = getline(&priv->line, &priv->linesize, priv->in)) == -1)
fatal("table-proc: getline");
priv->line[strcspn(priv->line, "\n")] = '\0';
l = priv->line;
if (n == 0) {
log_warnx("warn: table-proc: pipe closed");
break;
}
}
len = strlen(type);
if (strncmp(l, type, len) != 0)
goto err;
l += len;
if (*l != '|')
goto err;
l++;
len = strlen(priv->lastid);
if (strncmp(l, priv->lastid, len) != 0)
goto err;
l += len;
if (*l != '|')
goto err;
return (++l);
err:
log_warnx("warn: table-proc: failed to parse reply");
fatalx("table-proc: exiting");
}
static void
table_proc_read(void *dst, size_t len)
{
if (len > rlen) {
log_warnx("warn: table-proc: bad msg len");
fatalx("table-proc: exiting");
}
if (dst)
memmove(dst, rdata, len);
rlen -= len;
rdata += len;
}
static void
table_proc_end(void)
{
if (rlen) {
log_warnx("warn: table-proc: bogus data");
fatalx("table-proc: exiting");
}
imsg_free(&imsg);
}
/*
* API
*/
@ -106,24 +124,53 @@ static int
table_proc_open(struct table *table)
{
struct table_proc_priv *priv;
struct table_open_params op;
int fd;
const char *s;
ssize_t len;
int service, services = 0;
int fd, fdd;
priv = xcalloc(1, sizeof(*priv));
fd = fork_proc_backend("table", table->t_config, table->t_name);
fd = fork_proc_backend("table", table->t_config, table->t_name, 1);
if (fd == -1)
fatalx("table-proc: exiting");
if ((fdd = dup(fd)) == -1) {
log_warnx("warn: table-proc: dup");
fatalx("table-proc: exiting");
}
if ((priv->in = fdopen(fd, "r")) == NULL)
fatalx("table-proc: fdopen");
if ((priv->out = fdopen(fdd, "w")) == NULL)
fatalx("table-proc: fdopen");
imsg_init(&priv->ibuf, fd);
fprintf(priv->out, "config|smtpd-version|"SMTPD_VERSION"\n");
fprintf(priv->out, "config|protocol|"PROTOCOL_VERSION"\n");
fprintf(priv->out, "config|tablename|%s\n", table->t_name);
fprintf(priv->out, "config|ready\n");
if (fflush(priv->out) == EOF)
fatalx("table-proc: fflush");
memset(&op, 0, sizeof op);
op.version = PROC_TABLE_API_VERSION;
(void)strlcpy(op.name, table->t_name, sizeof op.name);
imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op);
while ((len = getline(&priv->line, &priv->linesize, priv->in)) != -1) {
priv->line[strcspn(priv->line, "\n")] = '\0';
table_proc_call(priv);
table_proc_end();
if (strncmp(priv->line, "register|", 9) != 0)
fatalx("table-proc: invalid handshake reply");
s = priv->line + 9;
if (!strcmp(s, "ready"))
break;
service = table_service_from_name(s);
if (service == -1 || service == K_NONE)
fatalx("table-proc: unknown service %s", s);
services |= service;
}
if (ferror(priv->in))
fatalx("table-proc: getline");
if (services == 0)
fatalx("table-proc: no services registered");
table->t_handle = priv;
@ -133,16 +180,17 @@ table_proc_open(struct table *table)
static int
table_proc_update(struct table *table)
{
struct table_proc_priv *priv = table->t_handle;
int r;
const char *r;
imsg_compose(&priv->ibuf, PROC_TABLE_UPDATE, 0, 0, -1, NULL, 0);
table_proc_send(table, "update", -1, NULL);
r = table_proc_recv(table, "update-result");
if (!strcmp(r, "ok"))
return (1);
if (!strcmp(r, "error"))
return (0);
table_proc_call(priv);
table_proc_read(&r, sizeof(r));
table_proc_end();
return (r);
log_warnx("warn: table-proc: failed parse reply");
fatalx("table-proc: exiting");
}
static void
@ -150,105 +198,85 @@ table_proc_close(struct table *table)
{
struct table_proc_priv *priv = table->t_handle;
imsg_compose(&priv->ibuf, PROC_TABLE_CLOSE, 0, 0, -1, NULL, 0);
if (imsg_flush(&priv->ibuf) == -1)
fatal("imsg_flush");
if (fclose(priv->in) == EOF)
fatal("table-proc: fclose");
if (fclose(priv->out) == EOF)
fatal("table-proc: fclose");
free(priv->line);
free(priv);
table->t_handle = NULL;
}
static int
imsg_add_params(struct ibuf *buf)
{
size_t count = 0;
if (imsg_add(buf, &count, sizeof(count)) == -1)
return (-1);
return (0);
}
static int
table_proc_lookup(struct table *table, enum table_service s, const char *k, char **dst)
{
struct table_proc_priv *priv = table->t_handle;
struct ibuf *buf;
int r;
const char *req = "lookup", *res = "lookup-result";
const char *r;
buf = imsg_create(&priv->ibuf,
dst ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0,
sizeof(s) + strlen(k) + 1);
if (buf == NULL)
return (-1);
if (imsg_add(buf, &s, sizeof(s)) == -1)
return (-1);
if (imsg_add_params(buf) == -1)
return (-1);
if (imsg_add(buf, k, strlen(k) + 1) == -1)
return (-1);
imsg_close(&priv->ibuf, buf);
table_proc_call(priv);
table_proc_read(&r, sizeof(r));
if (r == 1 && dst) {
if (rlen == 0) {
log_warnx("warn: table-proc: empty response");
fatalx("table-proc: exiting");
}
if (rdata[rlen - 1] != '\0') {
log_warnx("warn: table-proc: not NUL-terminated");
fatalx("table-proc: exiting");
}
*dst = strdup(rdata);
if (*dst == NULL)
r = -1;
table_proc_read(NULL, rlen);
if (dst == NULL) {
req = "check";
res = "check-result";
}
table_proc_end();
table_proc_send(table, req, s, k);
r = table_proc_recv(table, res);
return (r);
/* common replies */
if (!strcmp(r, "not-found"))
return (0);
if (!strcmp(r, "error"))
return (-1);
if (dst == NULL) {
/* check op */
if (!strncmp(r, "found", 5))
return (1);
log_warnx("warn: table-proc: failed to parse reply");
fatalx("table-proc: exiting");
}
/* lookup op */
if (strncmp(r, "found|", 6) != 0) {
log_warnx("warn: table-proc: failed to parse reply");
fatalx("table-proc: exiting");
}
r += 6;
if (*r == '\0') {
log_warnx("warn: table-proc: empty response");
fatalx("table-proc: exiting");
}
if ((*dst = strdup(r)) == NULL)
return (-1);
return (1);
}
static int
table_proc_fetch(struct table *table, enum table_service s, char **dst)
{
struct table_proc_priv *priv = table->t_handle;
struct ibuf *buf;
int r;
const char *r;
buf = imsg_create(&priv->ibuf, PROC_TABLE_FETCH, 0, 0, sizeof(s));
if (buf == NULL)
return (-1);
if (imsg_add(buf, &s, sizeof(s)) == -1)
return (-1);
if (imsg_add_params(buf) == -1)
return (-1);
imsg_close(&priv->ibuf, buf);
table_proc_send(table, "fetch", s, NULL);
r = table_proc_recv(table, "fetch-result");
table_proc_call(priv);
table_proc_read(&r, sizeof(r));
if (!strcmp(r, "not-found"))
return (0);
if (!strcmp(r, "error"))
return (-1);
if (r == 1) {
if (rlen == 0) {
log_warnx("warn: table-proc: empty response");
fatalx("table-proc: exiting");
}
if (rdata[rlen - 1] != '\0') {
log_warnx("warn: table-proc: not NUL-terminated");
fatalx("table-proc: exiting");
}
*dst = strdup(rdata);
if (*dst == NULL)
r = -1;
table_proc_read(NULL, rlen);
if (strncmp(r, "found|", 6) != 0) {
log_warnx("warn: table-proc: failed to parse reply");
fatalx("table-proc: exiting");
}
r += 6;
if (*r == '\0') {
log_warnx("warn: table-proc: empty response");
fatalx("table-proc: exiting");
}
table_proc_end();
return (r);
if ((*dst = strdup(r)) == NULL)
return (-1);
return (1);
}
struct table_backend table_backend_proc = {