sync with OpenBSD -current
This commit is contained in:
parent
382ecd9441
commit
1b576c8ddf
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: extern.h,v 1.62 2023/12/09 23:00:11 jca Exp $ */
|
/* $OpenBSD: extern.h,v 1.63 2024/04/16 18:52:43 jca Exp $ */
|
||||||
/* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */
|
/* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
@ -284,6 +284,7 @@ int tar_wr(ARCHD *);
|
|||||||
int ustar_id(char *, int);
|
int ustar_id(char *, int);
|
||||||
int ustar_rd(ARCHD *, char *);
|
int ustar_rd(ARCHD *, char *);
|
||||||
int ustar_wr(ARCHD *);
|
int ustar_wr(ARCHD *);
|
||||||
|
int pax_id(char *, int);
|
||||||
int pax_wr(ARCHD *);
|
int pax_wr(ARCHD *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: options.c,v 1.109 2024/04/15 22:07:08 caspar Exp $ */
|
/* $OpenBSD: options.c,v 1.112 2024/04/16 23:09:35 jca Exp $ */
|
||||||
/* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */
|
/* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
@ -228,7 +228,7 @@ FSUB fsub[] = {
|
|||||||
/* 9: gzip, to detect failure to use -z */
|
/* 9: gzip, to detect failure to use -z */
|
||||||
{NULL, 0, 4, 0, 0, 0, 0, gzip_id},
|
{NULL, 0, 4, 0, 0, 0, 0, gzip_id},
|
||||||
/* 10: POSIX PAX */
|
/* 10: POSIX PAX */
|
||||||
{"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, no_op,
|
{"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, pax_id, no_op,
|
||||||
ustar_rd, tar_endrd, no_op, pax_wr, tar_endwr, tar_trail,
|
ustar_rd, tar_endrd, no_op, pax_wr, tar_endwr, tar_trail,
|
||||||
tar_opt},
|
tar_opt},
|
||||||
#endif
|
#endif
|
||||||
@ -237,10 +237,11 @@ FSUB fsub[] = {
|
|||||||
#define F_ACPIO 1 /* format when called as cpio -c */
|
#define F_ACPIO 1 /* format when called as cpio -c */
|
||||||
#define F_CPIO 3 /* format when called as cpio */
|
#define F_CPIO 3 /* format when called as cpio */
|
||||||
#define F_OTAR 4 /* format when called as tar -o */
|
#define F_OTAR 4 /* format when called as tar -o */
|
||||||
#define F_TAR 5 /* format when called as tar */
|
|
||||||
#ifdef SMALL
|
#ifdef SMALL
|
||||||
|
# define F_TAR 5 /* default write format when called as tar: ustar */
|
||||||
# define DEFLT 5 /* default write format when called as pax: ustar */
|
# define DEFLT 5 /* default write format when called as pax: ustar */
|
||||||
#else
|
#else
|
||||||
|
# define F_TAR 10 /* default write format when called as tar: ustar */
|
||||||
# define DEFLT 10 /* default write format when called as pax: pax */
|
# define DEFLT 10 /* default write format when called as pax: pax */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -249,7 +250,7 @@ FSUB fsub[] = {
|
|||||||
* of archive we are dealing with. This helps to properly id archive formats
|
* of archive we are dealing with. This helps to properly id archive formats
|
||||||
* some formats may be subsets of others....
|
* some formats may be subsets of others....
|
||||||
*/
|
*/
|
||||||
int ford[] = {5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1};
|
int ford[] = {10, 5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do we have -C anywhere and what is it?
|
* Do we have -C anywhere and what is it?
|
||||||
@ -725,9 +726,10 @@ static void
|
|||||||
tar_options(int argc, char **argv)
|
tar_options(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int Oflag = 0;
|
|
||||||
int nincfiles = 0;
|
int nincfiles = 0;
|
||||||
int incfiles_max = 0;
|
int incfiles_max = 0;
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int format = F_TAR;
|
||||||
struct incfile {
|
struct incfile {
|
||||||
char *file;
|
char *file;
|
||||||
char *dir;
|
char *dir;
|
||||||
@ -743,7 +745,7 @@ tar_options(int argc, char **argv)
|
|||||||
* process option flags
|
* process option flags
|
||||||
*/
|
*/
|
||||||
while ((c = getoldopt(argc, argv,
|
while ((c = getoldopt(argc, argv,
|
||||||
"b:cef:hjmopqruts:vwxzBC:HI:LNOPXZ014578")) != -1) {
|
"b:cef:hjmopqruts:vwxzBC:F:HI:LNOPXZ014578")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
/*
|
/*
|
||||||
@ -792,10 +794,10 @@ tar_options(int argc, char **argv)
|
|||||||
pmtime = 0;
|
pmtime = 0;
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
Oflag = 1;
|
format = F_OTAR;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
Oflag = 2;
|
format = F_OTAR;
|
||||||
tar_nodir = 1;
|
tar_nodir = 1;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
@ -868,6 +870,24 @@ tar_options(int argc, char **argv)
|
|||||||
havechd++;
|
havechd++;
|
||||||
chdname = optarg;
|
chdname = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'F':
|
||||||
|
for (i = 0; i < sizeof(fsub)/sizeof(FSUB); ++i)
|
||||||
|
if (fsub[i].name != NULL &&
|
||||||
|
strcmp(fsub[i].name, optarg) == 0)
|
||||||
|
break;
|
||||||
|
if (i < sizeof(fsub)/sizeof(FSUB)) {
|
||||||
|
format = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
paxwarn(1, "Unknown -F format: %s", optarg);
|
||||||
|
(void)fputs("tar: Known -F formats are:", stderr);
|
||||||
|
for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
|
||||||
|
if (fsub[i].name != NULL)
|
||||||
|
(void)fprintf(stderr, " %s",
|
||||||
|
fsub[i].name);
|
||||||
|
(void)fputs("\n\n", stderr);
|
||||||
|
tar_usage();
|
||||||
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
/*
|
/*
|
||||||
* follow command line symlinks only
|
* follow command line symlinks only
|
||||||
@ -1042,7 +1062,7 @@ tar_options(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case ARCHIVE:
|
case ARCHIVE:
|
||||||
case APPND:
|
case APPND:
|
||||||
frmt = &(fsub[Oflag ? F_OTAR : F_TAR]);
|
frmt = &fsub[format];
|
||||||
|
|
||||||
if (chdname != NULL) { /* initial chdir() */
|
if (chdname != NULL) { /* initial chdir() */
|
||||||
if (ftree_add(chdname, 1) < 0)
|
if (ftree_add(chdname, 1) < 0)
|
||||||
@ -1704,11 +1724,12 @@ void
|
|||||||
tar_usage(void)
|
tar_usage(void)
|
||||||
{
|
{
|
||||||
(void)fputs(
|
(void)fputs(
|
||||||
"usage: tar {crtux}[014578befHhjLmNOoPpqsvwXZz]\n"
|
"usage: tar {crtux}[014578beFfHhjLmNOoPpqsvwXZz]\n"
|
||||||
" [blocking-factor | archive | replstr] [-C directory] [-I file]\n"
|
" [blocking-factor | format | archive | replstr]\n"
|
||||||
" [file ...]\n"
|
" [-C directory] [-I file] [file ...]\n"
|
||||||
" tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor]\n"
|
" tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor]\n"
|
||||||
" [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n",
|
" [-C directory] [-F format] [-f archive] [-I file]\n"
|
||||||
|
" [-s replstr] [file ...]\n",
|
||||||
stderr);
|
stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: tar.1,v 1.65 2023/08/03 18:17:54 aisha Exp $
|
.\" $OpenBSD: tar.1,v 1.67 2024/04/16 23:09:35 jca Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 1996 SigmaSoft, Th. Lockert
|
.\" Copyright (c) 1996 SigmaSoft, Th. Lockert
|
||||||
.\" All rights reserved.
|
.\" All rights reserved.
|
||||||
@ -23,7 +23,7 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: August 3 2023 $
|
.Dd $Mdocdate: April 16 2024 $
|
||||||
.Dt TAR 1
|
.Dt TAR 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -32,10 +32,10 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm tar
|
.Nm tar
|
||||||
.Sm off
|
.Sm off
|
||||||
.No { Cm crtux No } Op Cm 014578befHhjLmNOoPpqsvwXZz
|
.No { Cm crtux No } Op Cm 014578beFfHhjLmNOoPpqsvwXZz
|
||||||
.Sm on
|
.Sm on
|
||||||
.Bk -words
|
.Bk -words
|
||||||
.Op Ar blocking-factor | archive | replstr
|
.Op Ar blocking-factor | format | archive | replstr
|
||||||
.Op Fl C Ar directory
|
.Op Fl C Ar directory
|
||||||
.Op Fl I Ar file
|
.Op Fl I Ar file
|
||||||
.Op Ar
|
.Op Ar
|
||||||
@ -46,6 +46,7 @@
|
|||||||
.Op Fl 014578eHhjLmNOoPpqvwXZz
|
.Op Fl 014578eHhjLmNOoPpqvwXZz
|
||||||
.Op Fl b Ar blocking-factor
|
.Op Fl b Ar blocking-factor
|
||||||
.Op Fl C Ar directory
|
.Op Fl C Ar directory
|
||||||
|
.Op Fl F Ar format
|
||||||
.Op Fl f Ar archive
|
.Op Fl f Ar archive
|
||||||
.Op Fl I Ar file
|
.Op Fl I Ar file
|
||||||
.Op Fl s Ar replstr
|
.Op Fl s Ar replstr
|
||||||
@ -141,6 +142,77 @@ the specified directory; when creating, the specified files will be matched
|
|||||||
from the directory.
|
from the directory.
|
||||||
.It Fl e
|
.It Fl e
|
||||||
Stop after the first error.
|
Stop after the first error.
|
||||||
|
.It Fl F Ar format
|
||||||
|
Specify the output archive format, with the default format being
|
||||||
|
.Cm pax .
|
||||||
|
.Nm
|
||||||
|
currently supports the following formats:
|
||||||
|
.Bl -tag -width "sv4cpio"
|
||||||
|
.It Cm bcpio
|
||||||
|
The old binary cpio format.
|
||||||
|
The default blocksize for this format is 5120 bytes.
|
||||||
|
This format is not very portable and should not be used when other formats
|
||||||
|
are available.
|
||||||
|
Inode and device information about a file (used for detecting file hard links
|
||||||
|
by this format), which may be truncated by this format, is detected by
|
||||||
|
.Nm
|
||||||
|
and is repaired.
|
||||||
|
.It Cm cpio
|
||||||
|
The extended cpio interchange format specified in the
|
||||||
|
.St -p1003.2
|
||||||
|
standard.
|
||||||
|
The default blocksize for this format is 5120 bytes.
|
||||||
|
Inode and device information about a file (used for detecting file hard links
|
||||||
|
by this format), which may be truncated by this format, is detected by
|
||||||
|
.Nm
|
||||||
|
and is repaired.
|
||||||
|
.It Cm sv4cpio
|
||||||
|
The System V release 4 cpio.
|
||||||
|
The default blocksize for this format is 5120 bytes.
|
||||||
|
Inode and device information about a file (used for detecting file hard links
|
||||||
|
by this format), which may be truncated by this format, is detected by
|
||||||
|
.Nm
|
||||||
|
and is repaired.
|
||||||
|
.It Cm sv4crc
|
||||||
|
The System V release 4 cpio with file CRC checksums.
|
||||||
|
The default blocksize for this format is 5120 bytes.
|
||||||
|
Inode and device information about a file (used for detecting file hard links
|
||||||
|
by this format), which may be truncated by this format, is detected by
|
||||||
|
.Nm
|
||||||
|
and is repaired.
|
||||||
|
.It Cm tar
|
||||||
|
The old
|
||||||
|
.Bx
|
||||||
|
tar format as found in
|
||||||
|
.Bx 4.3 .
|
||||||
|
The default blocksize for this format is 10240 bytes.
|
||||||
|
Pathnames stored by this format must be 100 characters or less in length.
|
||||||
|
Only regular files, hard links, soft links, and directories
|
||||||
|
will be archived (other file system types are not supported).
|
||||||
|
For backwards compatibility with even older tar formats, see the
|
||||||
|
description for
|
||||||
|
.Fl o .
|
||||||
|
.It Cm ustar
|
||||||
|
The extended tar interchange format specified in the
|
||||||
|
.St -p1003.2
|
||||||
|
standard.
|
||||||
|
The default blocksize for this format is 10240 bytes.
|
||||||
|
Filenames stored by this format must be 100 characters or less in length;
|
||||||
|
the total pathname must be 256 characters or less.
|
||||||
|
.It Cm pax
|
||||||
|
The pax interchange format specified in the
|
||||||
|
.St -p1003.1-2001
|
||||||
|
standard.
|
||||||
|
The default blocksize for this format is 5120 bytes.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
will detect and report any file that it is unable to store or extract
|
||||||
|
as the result of any specific archive format restrictions.
|
||||||
|
The individual archive formats may impose additional restrictions on use.
|
||||||
|
Typical archive format restrictions include (but are not limited to):
|
||||||
|
file pathname length, file size, link pathname length, and the type of the
|
||||||
|
file.
|
||||||
.It Fl f Ar archive
|
.It Fl f Ar archive
|
||||||
Read from or write to
|
Read from or write to
|
||||||
.Ar archive .
|
.Ar archive .
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tar.c,v 1.79 2024/01/20 17:34:50 jca Exp $ */
|
/* $OpenBSD: tar.c,v 1.84 2024/04/16 22:58:10 jca Exp $ */
|
||||||
/* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */
|
/* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
@ -62,9 +62,6 @@ struct xheader_record {
|
|||||||
/* shortest possible extended record: "5 a=\n" */
|
/* shortest possible extended record: "5 a=\n" */
|
||||||
#define MINXHDRSZ 5
|
#define MINXHDRSZ 5
|
||||||
|
|
||||||
/* longest record we'll accept */
|
|
||||||
#define MAXXHDRSZ BLKMULT
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routines for reading, writing and header identify of various versions of tar
|
* Routines for reading, writing and header identify of various versions of tar
|
||||||
*/
|
*/
|
||||||
@ -1135,7 +1132,7 @@ wr_ustar_or_pax(ARCHD *arcn, int ustar)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
#ifndef SMALL
|
#ifndef SMALL
|
||||||
else if (xheader_add(&xhdr, "linkpath", arcn->name) == -1) {
|
else if (xheader_add(&xhdr, "linkpath", arcn->ln_name) == -1) {
|
||||||
paxwarn(1, "Link name too long for pax %s",
|
paxwarn(1, "Link name too long for pax %s",
|
||||||
arcn->ln_name);
|
arcn->ln_name);
|
||||||
xheader_free(&xhdr);
|
xheader_free(&xhdr);
|
||||||
@ -1391,6 +1388,46 @@ ustar_wr(ARCHD *arcn)
|
|||||||
return wr_ustar_or_pax(arcn, 1);
|
return wr_ustar_or_pax(arcn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pax_id()
|
||||||
|
* determine if a block given to us is a valid pax header.
|
||||||
|
* Return:
|
||||||
|
* 0 if a pax header, -1 otherwise
|
||||||
|
*/
|
||||||
|
#ifndef SMALL
|
||||||
|
int
|
||||||
|
pax_id(char *blk, int size)
|
||||||
|
{
|
||||||
|
HD_USTAR *hd;
|
||||||
|
|
||||||
|
if (size < BLKMULT)
|
||||||
|
return(-1);
|
||||||
|
hd = (HD_USTAR *)blk;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for block of zero's first, a simple and fast test then check
|
||||||
|
* ustar magic cookie. We should use TMAGLEN, but some USTAR archive
|
||||||
|
* programs are fouled up and create archives missing the \0. Last we
|
||||||
|
* check the checksum and the type flag. If ok we have to assume it is
|
||||||
|
* a valid pax header.
|
||||||
|
*/
|
||||||
|
if (hd->prefix[0] == '\0' && hd->name[0] == '\0')
|
||||||
|
return(-1);
|
||||||
|
if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0)
|
||||||
|
return(-1);
|
||||||
|
if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
|
||||||
|
return(-1);
|
||||||
|
/*
|
||||||
|
* It is valid for a pax formatted archive not to start with
|
||||||
|
* a global header nor with an extended header. In that case
|
||||||
|
* we'll fall back to ustar in append mode.
|
||||||
|
*/
|
||||||
|
if (hd->typeflag == XHDRTYPE || hd->typeflag == GHDRTYPE)
|
||||||
|
return(0);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pax_wr()
|
* pax_wr()
|
||||||
* Write out a pax format archive.
|
* Write out a pax format archive.
|
||||||
@ -1548,7 +1585,11 @@ rd_size(off_t *size, const char *keyword, char *p)
|
|||||||
static int
|
static int
|
||||||
rd_xheader(ARCHD *arcn, int global, off_t size)
|
rd_xheader(ARCHD *arcn, int global, off_t size)
|
||||||
{
|
{
|
||||||
char buf[MAXXHDRSZ];
|
/*
|
||||||
|
* The pax format supposedly supports arbitrarily sized extended
|
||||||
|
* record headers, this implementation doesn't.
|
||||||
|
*/
|
||||||
|
char buf[sizeof("30xx linkpath=") - 1 + PAXPATHLEN + sizeof("\n")];
|
||||||
long len;
|
long len;
|
||||||
char *delim, *keyword;
|
char *delim, *keyword;
|
||||||
char *nextp, *p, *end;
|
char *nextp, *p, *end;
|
||||||
|
@ -2693,8 +2693,8 @@ X509_STORE_add_crl
|
|||||||
X509_STORE_add_lookup
|
X509_STORE_add_lookup
|
||||||
X509_STORE_free
|
X509_STORE_free
|
||||||
X509_STORE_get0_objects
|
X509_STORE_get0_objects
|
||||||
X509_STORE_get1_objects
|
|
||||||
X509_STORE_get0_param
|
X509_STORE_get0_param
|
||||||
|
X509_STORE_get1_objects
|
||||||
X509_STORE_get_check_issued
|
X509_STORE_get_check_issued
|
||||||
X509_STORE_get_ex_data
|
X509_STORE_get_ex_data
|
||||||
X509_STORE_get_verify
|
X509_STORE_get_verify
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: bn_convert.c,v 1.15 2023/07/09 18:37:58 tb Exp $ */
|
/* $OpenBSD: bn_convert.c,v 1.18 2024/04/16 13:14:46 jsing Exp $ */
|
||||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -153,46 +153,69 @@ BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
|
|||||||
}
|
}
|
||||||
LCRYPTO_ALIAS(BN_bn2binpad);
|
LCRYPTO_ALIAS(BN_bn2binpad);
|
||||||
|
|
||||||
BIGNUM *
|
static int
|
||||||
BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
|
bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
||||||
{
|
{
|
||||||
unsigned int i, m;
|
|
||||||
unsigned int n;
|
|
||||||
BN_ULONG l;
|
|
||||||
BIGNUM *bn = NULL;
|
BIGNUM *bn = NULL;
|
||||||
|
BN_ULONG w;
|
||||||
|
uint8_t v;
|
||||||
|
int b, i;
|
||||||
|
|
||||||
if (len < 0)
|
if ((bn = *bnp) == NULL)
|
||||||
return (NULL);
|
bn = BN_new();
|
||||||
if (ret == NULL)
|
if (bn == NULL)
|
||||||
ret = bn = BN_new();
|
goto err;
|
||||||
if (ret == NULL)
|
if (!bn_expand_bytes(bn, CBS_len(cbs)))
|
||||||
return (NULL);
|
goto err;
|
||||||
l = 0;
|
|
||||||
n = len;
|
b = 0;
|
||||||
if (n == 0) {
|
i = 0;
|
||||||
ret->top = 0;
|
w = 0;
|
||||||
return (ret);
|
|
||||||
}
|
while (CBS_len(cbs) > 0) {
|
||||||
i = ((n - 1) / BN_BYTES) + 1;
|
if (!CBS_get_last_u8(cbs, &v))
|
||||||
m = ((n - 1) % (BN_BYTES));
|
goto err;
|
||||||
if (!bn_wexpand(ret, (int)i)) {
|
|
||||||
BN_free(bn);
|
w |= (BN_ULONG)v << b;
|
||||||
return NULL;
|
b += 8;
|
||||||
}
|
|
||||||
ret->top = i;
|
if (b == BN_BITS2 || CBS_len(cbs) == 0) {
|
||||||
ret->neg = 0;
|
b = 0;
|
||||||
while (n--) {
|
bn->d[i++] = w;
|
||||||
l = (l << 8L) | *(s++);
|
w = 0;
|
||||||
if (m-- == 0) {
|
|
||||||
ret->d[--i] = l;
|
|
||||||
l = 0;
|
|
||||||
m = BN_BYTES - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* need to call this due to clear byte at top if avoiding
|
|
||||||
* having the top bit set (-ve number) */
|
bn->neg = 0;
|
||||||
bn_correct_top(ret);
|
bn->top = i;
|
||||||
return (ret);
|
|
||||||
|
bn_correct_top(bn);
|
||||||
|
|
||||||
|
*bnp = bn;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (*bnp == NULL)
|
||||||
|
BN_free(bn);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIGNUM *
|
||||||
|
BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn)
|
||||||
|
{
|
||||||
|
CBS cbs;
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CBS_init(&cbs, d, len);
|
||||||
|
|
||||||
|
if (!bn_bin2bn_cbs(&bn, &cbs))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return bn;
|
||||||
}
|
}
|
||||||
LCRYPTO_ALIAS(BN_bin2bn);
|
LCRYPTO_ALIAS(BN_bin2bn);
|
||||||
|
|
||||||
@ -431,7 +454,7 @@ bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
|||||||
bn = BN_new();
|
bn = BN_new();
|
||||||
if (bn == NULL)
|
if (bn == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
if (!bn_expand(bn, digits * 4))
|
if (!bn_expand_bits(bn, digits * 4))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if ((d = digits % BN_DEC_NUM) == 0)
|
if ((d = digits % BN_DEC_NUM) == 0)
|
||||||
@ -628,13 +651,13 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
|||||||
bn = BN_new();
|
bn = BN_new();
|
||||||
if (bn == NULL)
|
if (bn == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
if (!bn_expand(bn, digits * 4))
|
if (!bn_expand_bits(bn, digits * 4))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (!CBS_get_bytes(cbs, cbs, digits))
|
if (!CBS_get_bytes(cbs, cbs, digits))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
b = BN_BITS2;
|
b = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
w = 0;
|
w = 0;
|
||||||
|
|
||||||
@ -652,11 +675,11 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
|||||||
else
|
else
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
w |= (BN_ULONG)v << (BN_BITS2 - b);
|
w |= (BN_ULONG)v << b;
|
||||||
b -= 4;
|
b += 4;
|
||||||
|
|
||||||
if (b == 0 || digits == 0) {
|
if (b == BN_BITS2 || digits == 0) {
|
||||||
b = BN_BITS2;
|
b = 0;
|
||||||
bn->d[i++] = w;
|
bn->d[i++] = w;
|
||||||
w = 0;
|
w = 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: bn_lib.c,v 1.91 2024/04/15 14:35:25 jsing Exp $ */
|
/* $OpenBSD: bn_lib.c,v 1.93 2024/04/16 13:07:14 jsing Exp $ */
|
||||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -219,13 +219,10 @@ bn_expand_internal(BIGNUM *bn, int words)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bn_expand(BIGNUM *bn, int bits)
|
bn_expand_bits(BIGNUM *bn, size_t bits)
|
||||||
{
|
{
|
||||||
int words;
|
int words;
|
||||||
|
|
||||||
if (bits < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (bits > (INT_MAX - BN_BITS2 + 1))
|
if (bits > (INT_MAX - BN_BITS2 + 1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -234,6 +231,19 @@ bn_expand(BIGNUM *bn, int bits)
|
|||||||
return bn_wexpand(bn, words);
|
return bn_wexpand(bn, words);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bn_expand_bytes(BIGNUM *bn, size_t bytes)
|
||||||
|
{
|
||||||
|
int words;
|
||||||
|
|
||||||
|
if (bytes > (INT_MAX - BN_BYTES + 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
words = (bytes + BN_BYTES - 1) / BN_BYTES;
|
||||||
|
|
||||||
|
return bn_wexpand(bn, words);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bn_wexpand(BIGNUM *bn, int words)
|
bn_wexpand(BIGNUM *bn, int words)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: bn_local.h,v 1.41 2024/04/10 15:09:03 tb Exp $ */
|
/* $OpenBSD: bn_local.h,v 1.43 2024/04/16 13:07:14 jsing Exp $ */
|
||||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -259,7 +259,8 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
|||||||
const BN_ULONG *np, const BN_ULONG *n0, int num);
|
const BN_ULONG *np, const BN_ULONG *n0, int num);
|
||||||
|
|
||||||
void bn_correct_top(BIGNUM *a);
|
void bn_correct_top(BIGNUM *a);
|
||||||
int bn_expand(BIGNUM *a, int bits);
|
int bn_expand_bits(BIGNUM *a, size_t bits);
|
||||||
|
int bn_expand_bytes(BIGNUM *a, size_t bytes);
|
||||||
int bn_wexpand(BIGNUM *a, int words);
|
int bn_wexpand(BIGNUM *a, int words);
|
||||||
|
|
||||||
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssl_tlsext.c,v 1.148 2024/04/04 08:02:21 tb Exp $ */
|
/* $OpenBSD: ssl_tlsext.c,v 1.149 2024/04/16 17:46:30 tb Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
|
* Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
|
||||||
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
|
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
|
||||||
@ -1493,6 +1493,45 @@ tlsext_keyshare_server_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->s3->hs.tls13.hrr) {
|
||||||
|
if (!CBS_get_u16_length_prefixed(cbs, &client_shares))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Unpack client share. */
|
||||||
|
if (!CBS_get_u16(&client_shares, &group))
|
||||||
|
return 0;
|
||||||
|
if (!CBS_get_u16_length_prefixed(&client_shares, &key_exchange))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* There should only be one share. */
|
||||||
|
if (CBS_len(&client_shares) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (group != s->s3->hs.tls13.server_group) {
|
||||||
|
*alert = SSL_AD_ILLEGAL_PARAMETER;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->s3->hs.key_share != NULL) {
|
||||||
|
*alert = SSL_AD_INTERNAL_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode and store the selected key share. */
|
||||||
|
if ((s->s3->hs.key_share = tls_key_share_new(group)) == NULL) {
|
||||||
|
*alert = SSL_AD_INTERNAL_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!tls_key_share_peer_public(s->s3->hs.key_share,
|
||||||
|
&key_exchange, &decode_error, NULL)) {
|
||||||
|
if (!decode_error)
|
||||||
|
*alert = SSL_AD_INTERNAL_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX similar to tls1_get_supported_group, but client pref
|
* XXX similar to tls1_get_supported_group, but client pref
|
||||||
* only - consider deduping later.
|
* only - consider deduping later.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* $OpenBSD: spleen32x64.h,v 1.9 2020/07/31 20:14:47 fcambus Exp $ */
|
/* $OpenBSD: spleen32x64.h,v 1.10 2024/04/16 17:15:15 fcambus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2020 Frederic Cambus <fcambus@openbsd.org>
|
* Copyright (c) 2018-2024 Frederic Cambus <fcambus@openbsd.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -5616,11 +5616,11 @@ static u_char spleen32x64_data[] = {
|
|||||||
0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */
|
0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */
|
||||||
0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */
|
0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */
|
||||||
0x0f, 0x80, 0x00, 0xf0, /* ....*****...............****.... */
|
0x0f, 0x80, 0x00, 0xf0, /* ....*****...............****.... */
|
||||||
0x0f, 0xc0, 0x00, 0xf0, /* ....******..............****.... */
|
0x07, 0xc0, 0x00, 0xf0, /* .....*****..............****.... */
|
||||||
0x07, 0xff, 0xff, 0xf0, /* .....***********************.... */
|
0x07, 0xff, 0xff, 0xf0, /* .....***********************.... */
|
||||||
0x03, 0xff, 0xff, 0xf0, /* ......**********************.... */
|
0x03, 0xff, 0xff, 0xf0, /* ......**********************.... */
|
||||||
0x01, 0xff, 0xff, 0xf0, /* .......*********************.... */
|
0x01, 0xff, 0xff, 0xf0, /* .......*********************.... */
|
||||||
0x00, 0xff, 0xff, 0xf0, /* ........********************.... */
|
0x00, 0x7f, 0xff, 0xf0, /* .........*******************.... */
|
||||||
0x00, 0x00, 0x00, 0x00, /* ................................ */
|
0x00, 0x00, 0x00, 0x00, /* ................................ */
|
||||||
0x00, 0x00, 0x00, 0x00, /* ................................ */
|
0x00, 0x00, 0x00, 0x00, /* ................................ */
|
||||||
0x00, 0x00, 0x00, 0x00, /* ................................ */
|
0x00, 0x00, 0x00, 0x00, /* ................................ */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ip_input.c,v 1.392 2024/04/14 20:46:27 bluhm Exp $ */
|
/* $OpenBSD: ip_input.c,v 1.393 2024/04/16 12:56:39 bluhm Exp $ */
|
||||||
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
|
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -138,7 +138,7 @@ extern struct niqueue arpinq;
|
|||||||
|
|
||||||
int ip_ours(struct mbuf **, int *, int, int);
|
int ip_ours(struct mbuf **, int *, int, int);
|
||||||
int ip_dooptions(struct mbuf *, struct ifnet *);
|
int ip_dooptions(struct mbuf *, struct ifnet *);
|
||||||
int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **);
|
int in_ouraddr(struct mbuf *, struct ifnet *, struct route *);
|
||||||
|
|
||||||
int ip_fragcheck(struct mbuf **, int *);
|
int ip_fragcheck(struct mbuf **, int *);
|
||||||
struct mbuf * ip_reass(struct ipqent *, struct ipq *);
|
struct mbuf * ip_reass(struct ipqent *, struct ipq *);
|
||||||
@ -424,9 +424,9 @@ bad:
|
|||||||
int
|
int
|
||||||
ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
struct mbuf *m;
|
struct route ro;
|
||||||
struct rtentry *rt = NULL;
|
struct mbuf *m;
|
||||||
struct ip *ip;
|
struct ip *ip;
|
||||||
int hlen;
|
int hlen;
|
||||||
#if NPF > 0
|
#if NPF > 0
|
||||||
struct in_addr odst;
|
struct in_addr odst;
|
||||||
@ -435,6 +435,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
|||||||
|
|
||||||
KASSERT(*offp == 0);
|
KASSERT(*offp == 0);
|
||||||
|
|
||||||
|
ro.ro_rt = NULL;
|
||||||
ipstat_inc(ips_total);
|
ipstat_inc(ips_total);
|
||||||
m = *mp = ipv4_check(ifp, *mp);
|
m = *mp = ipv4_check(ifp, *mp);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
@ -482,7 +483,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(in_ouraddr(m, ifp, &rt)) {
|
switch(in_ouraddr(m, ifp, &ro)) {
|
||||||
case 2:
|
case 2:
|
||||||
goto bad;
|
goto bad;
|
||||||
case 1:
|
case 1:
|
||||||
@ -584,14 +585,14 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
|||||||
}
|
}
|
||||||
#endif /* IPSEC */
|
#endif /* IPSEC */
|
||||||
|
|
||||||
ip_forward(m, ifp, rt, pfrdr);
|
ip_forward(m, ifp, &ro, pfrdr);
|
||||||
*mp = NULL;
|
*mp = NULL;
|
||||||
return IPPROTO_DONE;
|
return IPPROTO_DONE;
|
||||||
bad:
|
bad:
|
||||||
nxt = IPPROTO_DONE;
|
nxt = IPPROTO_DONE;
|
||||||
m_freemp(mp);
|
m_freemp(mp);
|
||||||
out:
|
out:
|
||||||
rtfree(rt);
|
rtfree(ro.ro_rt);
|
||||||
return nxt;
|
return nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,11 +806,10 @@ ip_deliver(struct mbuf **mp, int *offp, int nxt, int af, int shared)
|
|||||||
#undef IPSTAT_INC
|
#undef IPSTAT_INC
|
||||||
|
|
||||||
int
|
int
|
||||||
in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
|
in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct route *ro)
|
||||||
{
|
{
|
||||||
struct rtentry *rt;
|
struct rtentry *rt;
|
||||||
struct ip *ip;
|
struct ip *ip;
|
||||||
struct sockaddr_in sin;
|
|
||||||
int match = 0;
|
int match = 0;
|
||||||
|
|
||||||
#if NPF > 0
|
#if NPF > 0
|
||||||
@ -826,13 +826,8 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
|
|||||||
|
|
||||||
ip = mtod(m, struct ip *);
|
ip = mtod(m, struct ip *);
|
||||||
|
|
||||||
memset(&sin, 0, sizeof(sin));
|
rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
|
||||||
sin.sin_len = sizeof(sin);
|
if (rt != NULL) {
|
||||||
sin.sin_family = AF_INET;
|
|
||||||
sin.sin_addr = ip->ip_dst;
|
|
||||||
rt = rtalloc_mpath(sintosa(&sin), &ip->ip_src.s_addr,
|
|
||||||
m->m_pkthdr.ph_rtableid);
|
|
||||||
if (rtisvalid(rt)) {
|
|
||||||
if (ISSET(rt->rt_flags, RTF_LOCAL))
|
if (ISSET(rt->rt_flags, RTF_LOCAL))
|
||||||
match = 1;
|
match = 1;
|
||||||
|
|
||||||
@ -848,7 +843,6 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
|
|||||||
m->m_flags |= M_BCAST;
|
m->m_flags |= M_BCAST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*prt = rt;
|
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
struct ifaddr *ifa;
|
struct ifaddr *ifa;
|
||||||
@ -1527,11 +1521,12 @@ const u_char inetctlerrmap[PRC_NCMDS] = {
|
|||||||
* via a source route.
|
* via a source route.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
|
ip_forward(struct mbuf *m, struct ifnet *ifp, struct route *ro, int srcrt)
|
||||||
{
|
{
|
||||||
struct mbuf mfake, *mcopy;
|
struct mbuf mfake, *mcopy;
|
||||||
struct ip *ip = mtod(m, struct ip *);
|
struct ip *ip = mtod(m, struct ip *);
|
||||||
struct route ro;
|
struct route iproute;
|
||||||
|
struct rtentry *rt;
|
||||||
int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len;
|
int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len;
|
||||||
u_int32_t dest;
|
u_int32_t dest;
|
||||||
|
|
||||||
@ -1546,19 +1541,16 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ro.ro_rt = NULL;
|
if (ro == NULL) {
|
||||||
route_cache(&ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
|
ro = &iproute;
|
||||||
if (!rtisvalid(rt)) {
|
ro->ro_rt = NULL;
|
||||||
rtfree(rt);
|
}
|
||||||
rt = rtalloc_mpath(&ro.ro_dstsa, &ip->ip_src.s_addr,
|
rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
|
||||||
m->m_pkthdr.ph_rtableid);
|
if (rt == NULL) {
|
||||||
if (rt == NULL) {
|
ipstat_inc(ips_noroute);
|
||||||
ipstat_inc(ips_noroute);
|
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
|
||||||
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
|
goto done;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ro.ro_rt = rt;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save at most 68 bytes of the packet in case
|
* Save at most 68 bytes of the packet in case
|
||||||
@ -1609,10 +1601,10 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ip_output(m, NULL, &ro,
|
error = ip_output(m, NULL, ro,
|
||||||
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
|
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0);
|
||||||
rt = ro.ro_rt;
|
rt = ro->ro_rt;
|
||||||
if (error)
|
if (error)
|
||||||
ipstat_inc(ips_cantforward);
|
ipstat_inc(ips_cantforward);
|
||||||
else {
|
else {
|
||||||
@ -1680,9 +1672,10 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
|
|||||||
icmp_error(mcopy, type, code, dest, destmtu);
|
icmp_error(mcopy, type, code, dest, destmtu);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if (ro == &iproute)
|
||||||
|
rtfree(ro->ro_rt);
|
||||||
if (fake)
|
if (fake)
|
||||||
m_tag_delete_chain(&mfake);
|
m_tag_delete_chain(&mfake);
|
||||||
rtfree(rt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ip_var.h,v 1.115 2024/04/14 20:46:27 bluhm Exp $ */
|
/* $OpenBSD: ip_var.h,v 1.116 2024/04/16 12:56:39 bluhm Exp $ */
|
||||||
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
|
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -260,7 +260,7 @@ void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
|
|||||||
struct mbuf *);
|
struct mbuf *);
|
||||||
int ip_input_if(struct mbuf **, int *, int, int, struct ifnet *);
|
int ip_input_if(struct mbuf **, int *, int, int, struct ifnet *);
|
||||||
int ip_deliver(struct mbuf **, int *, int, int, int);
|
int ip_deliver(struct mbuf **, int *, int, int, int);
|
||||||
void ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int);
|
void ip_forward(struct mbuf *, struct ifnet *, struct route *, int);
|
||||||
int rip_ctloutput(int, struct socket *, int, int, struct mbuf *);
|
int rip_ctloutput(int, struct socket *, int, int, struct mbuf *);
|
||||||
void rip_init(void);
|
void rip_init(void);
|
||||||
int rip_input(struct mbuf **, int *, int, int);
|
int rip_input(struct mbuf **, int *, int, int);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: in6.c,v 1.262 2023/06/28 11:49:49 kn Exp $ */
|
/* $OpenBSD: in6.c,v 1.263 2024/04/16 14:37:49 florian Exp $ */
|
||||||
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
|
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -565,7 +565,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
|
|||||||
* The destination address for a p2p link must have a family
|
* The destination address for a p2p link must have a family
|
||||||
* of AF_UNSPEC or AF_INET6.
|
* of AF_UNSPEC or AF_INET6.
|
||||||
*/
|
*/
|
||||||
if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
|
if ((ifp->if_flags & IFF_POINTOPOINT) &&
|
||||||
ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
|
ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
|
||||||
ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
|
ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
|
||||||
return (EAFNOSUPPORT);
|
return (EAFNOSUPPORT);
|
||||||
@ -603,19 +603,18 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
|
|||||||
* zone identifier.
|
* zone identifier.
|
||||||
*/
|
*/
|
||||||
dst6 = ifra->ifra_dstaddr;
|
dst6 = ifra->ifra_dstaddr;
|
||||||
if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
|
if ((ifp->if_flags & IFF_POINTOPOINT) &&
|
||||||
(dst6.sin6_family == AF_INET6)) {
|
(dst6.sin6_family == AF_INET6)) {
|
||||||
error = in6_check_embed_scope(&dst6, ifp->if_index);
|
error = in6_check_embed_scope(&dst6, ifp->if_index);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* The destination address can be specified only for a p2p or a
|
* The destination address can be specified only for a p2p interface.
|
||||||
* loopback interface. If specified, the corresponding prefix length
|
* If specified, the corresponding prefix length must be 128.
|
||||||
* must be 128.
|
|
||||||
*/
|
*/
|
||||||
if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
|
if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
|
||||||
if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0)
|
if (!(ifp->if_flags & IFF_POINTOPOINT))
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
if (plen != 128)
|
if (plen != 128)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
@ -652,7 +651,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
|
|||||||
ia6->ia_addr.sin6_family = AF_INET6;
|
ia6->ia_addr.sin6_family = AF_INET6;
|
||||||
ia6->ia_addr.sin6_len = sizeof(ia6->ia_addr);
|
ia6->ia_addr.sin6_len = sizeof(ia6->ia_addr);
|
||||||
ia6->ia6_updatetime = getuptime();
|
ia6->ia6_updatetime = getuptime();
|
||||||
if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
|
if (ifp->if_flags & IFF_POINTOPOINT) {
|
||||||
/*
|
/*
|
||||||
* XXX: some functions expect that ifa_dstaddr is not
|
* XXX: some functions expect that ifa_dstaddr is not
|
||||||
* NULL for p2p interfaces.
|
* NULL for p2p interfaces.
|
||||||
@ -687,7 +686,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
|
|||||||
/*
|
/*
|
||||||
* If a new destination address is specified, scrub the old one and
|
* If a new destination address is specified, scrub the old one and
|
||||||
* install the new destination. Note that the interface must be
|
* install the new destination. Note that the interface must be
|
||||||
* p2p or loopback (see the check above.)
|
* p2p (see the check above.)
|
||||||
*/
|
*/
|
||||||
if ((ifp->if_flags & IFF_POINTOPOINT) && dst6.sin6_family == AF_INET6 &&
|
if ((ifp->if_flags & IFF_POINTOPOINT) && dst6.sin6_family == AF_INET6 &&
|
||||||
!IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) {
|
!IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: in6_proto.c,v 1.113 2024/01/11 14:15:12 bluhm Exp $ */
|
/* $OpenBSD: in6_proto.c,v 1.114 2024/04/16 12:40:40 bluhm Exp $ */
|
||||||
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
|
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -158,7 +158,7 @@ const struct protosw inet6sw[] = {
|
|||||||
.pr_type = SOCK_RAW,
|
.pr_type = SOCK_RAW,
|
||||||
.pr_domain = &inet6domain,
|
.pr_domain = &inet6domain,
|
||||||
.pr_protocol = IPPROTO_RAW,
|
.pr_protocol = IPPROTO_RAW,
|
||||||
.pr_flags = PR_ATOMIC|PR_ADDR,
|
.pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
|
||||||
.pr_input = rip6_input,
|
.pr_input = rip6_input,
|
||||||
.pr_ctlinput = rip6_ctlinput,
|
.pr_ctlinput = rip6_ctlinput,
|
||||||
.pr_ctloutput = rip6_ctloutput,
|
.pr_ctloutput = rip6_ctloutput,
|
||||||
@ -322,7 +322,7 @@ const struct protosw inet6sw[] = {
|
|||||||
/* raw wildcard */
|
/* raw wildcard */
|
||||||
.pr_type = SOCK_RAW,
|
.pr_type = SOCK_RAW,
|
||||||
.pr_domain = &inet6domain,
|
.pr_domain = &inet6domain,
|
||||||
.pr_flags = PR_ATOMIC|PR_ADDR,
|
.pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
|
||||||
.pr_input = rip6_input,
|
.pr_input = rip6_input,
|
||||||
.pr_ctloutput = rip6_ctloutput,
|
.pr_ctloutput = rip6_ctloutput,
|
||||||
.pr_usrreqs = &rip6_usrreqs,
|
.pr_usrreqs = &rip6_usrreqs,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ip6_forward.c,v 1.116 2024/02/28 10:57:20 bluhm Exp $ */
|
/* $OpenBSD: ip6_forward.c,v 1.117 2024/04/16 12:56:39 bluhm Exp $ */
|
||||||
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
|
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -82,11 +82,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ip6_forward(struct mbuf *m, struct rtentry *rt, int srcrt)
|
ip6_forward(struct mbuf *m, struct route *ro, int srcrt)
|
||||||
{
|
{
|
||||||
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
|
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
|
||||||
|
struct route iproute;
|
||||||
|
struct rtentry *rt;
|
||||||
struct sockaddr *dst;
|
struct sockaddr *dst;
|
||||||
struct route ro;
|
|
||||||
struct ifnet *ifp = NULL;
|
struct ifnet *ifp = NULL;
|
||||||
int error = 0, type = 0, code = 0, destmtu = 0;
|
int error = 0, type = 0, code = 0, destmtu = 0;
|
||||||
struct mbuf *mcopy;
|
struct mbuf *mcopy;
|
||||||
@ -165,25 +166,22 @@ reroute:
|
|||||||
}
|
}
|
||||||
#endif /* IPSEC */
|
#endif /* IPSEC */
|
||||||
|
|
||||||
ro.ro_rt = NULL;
|
if (ro == NULL) {
|
||||||
route6_cache(&ro, &ip6->ip6_dst, &ip6->ip6_src,
|
ro = &iproute;
|
||||||
m->m_pkthdr.ph_rtableid);
|
ro->ro_rt = NULL;
|
||||||
dst = &ro.ro_dstsa;
|
|
||||||
if (!rtisvalid(rt)) {
|
|
||||||
rtfree(rt);
|
|
||||||
rt = rtalloc_mpath(dst, &ip6->ip6_src.s6_addr32[0],
|
|
||||||
m->m_pkthdr.ph_rtableid);
|
|
||||||
if (rt == NULL) {
|
|
||||||
ip6stat_inc(ip6s_noroute);
|
|
||||||
if (mcopy != NULL) {
|
|
||||||
icmp6_error(mcopy, ICMP6_DST_UNREACH,
|
|
||||||
ICMP6_DST_UNREACH_NOROUTE, 0);
|
|
||||||
}
|
|
||||||
m_freem(m);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ro.ro_rt = rt;
|
rt = route6_mpath(ro, &ip6->ip6_dst, &ip6->ip6_src,
|
||||||
|
m->m_pkthdr.ph_rtableid);
|
||||||
|
if (rt == NULL) {
|
||||||
|
ip6stat_inc(ip6s_noroute);
|
||||||
|
if (mcopy != NULL) {
|
||||||
|
icmp6_error(mcopy, ICMP6_DST_UNREACH,
|
||||||
|
ICMP6_DST_UNREACH_NOROUTE, 0);
|
||||||
|
}
|
||||||
|
m_freem(m);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
dst = &ro->ro_dstsa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scope check: if a packet can't be delivered to its destination
|
* Scope check: if a packet can't be delivered to its destination
|
||||||
@ -225,8 +223,8 @@ reroute:
|
|||||||
*/
|
*/
|
||||||
if (tdb != NULL) {
|
if (tdb != NULL) {
|
||||||
/* Callee frees mbuf */
|
/* Callee frees mbuf */
|
||||||
error = ip6_output_ipsec_send(tdb, m, &ro, 0, 1);
|
error = ip6_output_ipsec_send(tdb, m, ro, 0, 1);
|
||||||
rt = ro.ro_rt;
|
rt = ro->ro_rt;
|
||||||
if (error)
|
if (error)
|
||||||
goto senderr;
|
goto senderr;
|
||||||
goto freecopy;
|
goto freecopy;
|
||||||
@ -254,7 +252,7 @@ reroute:
|
|||||||
ip6_sendredirects &&
|
ip6_sendredirects &&
|
||||||
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
|
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
|
||||||
if ((ifp->if_flags & IFF_POINTOPOINT) &&
|
if ((ifp->if_flags & IFF_POINTOPOINT) &&
|
||||||
nd6_is_addr_neighbor(&ro.ro_dstsin6, ifp)) {
|
nd6_is_addr_neighbor(&ro->ro_dstsin6, ifp)) {
|
||||||
/*
|
/*
|
||||||
* If the incoming interface is equal to the outgoing
|
* If the incoming interface is equal to the outgoing
|
||||||
* one, the link attached to the interface is
|
* one, the link attached to the interface is
|
||||||
@ -308,8 +306,9 @@ reroute:
|
|||||||
/* tag as generated to skip over pf_test on rerun */
|
/* tag as generated to skip over pf_test on rerun */
|
||||||
m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
|
m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
|
||||||
srcrt = 1;
|
srcrt = 1;
|
||||||
rtfree(rt);
|
if (ro == &iproute)
|
||||||
rt = NULL;
|
rtfree(ro->ro_rt);
|
||||||
|
ro = NULL;
|
||||||
if_put(ifp);
|
if_put(ifp);
|
||||||
ifp = NULL;
|
ifp = NULL;
|
||||||
goto reroute;
|
goto reroute;
|
||||||
@ -388,7 +387,8 @@ senderr:
|
|||||||
freecopy:
|
freecopy:
|
||||||
m_freem(mcopy);
|
m_freem(mcopy);
|
||||||
done:
|
done:
|
||||||
rtfree(rt);
|
if (ro == &iproute)
|
||||||
|
rtfree(ro->ro_rt);
|
||||||
if_put(ifp);
|
if_put(ifp);
|
||||||
#ifdef IPSEC
|
#ifdef IPSEC
|
||||||
tdb_unref(tdb);
|
tdb_unref(tdb);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ip6_input.c,v 1.260 2024/04/14 20:46:27 bluhm Exp $ */
|
/* $OpenBSD: ip6_input.c,v 1.261 2024/04/16 12:56:39 bluhm Exp $ */
|
||||||
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
|
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -356,10 +356,10 @@ bad:
|
|||||||
int
|
int
|
||||||
ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
|
struct route ro;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
struct ip6_hdr *ip6;
|
struct ip6_hdr *ip6;
|
||||||
struct sockaddr_in6 sin6;
|
struct rtentry *rt;
|
||||||
struct rtentry *rt = NULL;
|
|
||||||
int ours = 0;
|
int ours = 0;
|
||||||
u_int16_t src_scope, dst_scope;
|
u_int16_t src_scope, dst_scope;
|
||||||
#if NPF > 0
|
#if NPF > 0
|
||||||
@ -369,8 +369,8 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
|||||||
|
|
||||||
KASSERT(*offp == 0);
|
KASSERT(*offp == 0);
|
||||||
|
|
||||||
|
ro.ro_rt = NULL;
|
||||||
ip6stat_inc(ip6s_total);
|
ip6stat_inc(ip6s_total);
|
||||||
|
|
||||||
m = *mp = ipv6_check(ifp, *mp);
|
m = *mp = ipv6_check(ifp, *mp);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -516,18 +516,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
|||||||
/*
|
/*
|
||||||
* Unicast check
|
* Unicast check
|
||||||
*/
|
*/
|
||||||
memset(&sin6, 0, sizeof(struct sockaddr_in6));
|
rt = route6_mpath(&ro, &ip6->ip6_dst, &ip6->ip6_src,
|
||||||
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
|
||||||
sin6.sin6_family = AF_INET6;
|
|
||||||
sin6.sin6_addr = ip6->ip6_dst;
|
|
||||||
rt = rtalloc_mpath(sin6tosa(&sin6), &ip6->ip6_src.s6_addr32[0],
|
|
||||||
m->m_pkthdr.ph_rtableid);
|
m->m_pkthdr.ph_rtableid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accept the packet if the route to the destination is marked
|
* Accept the packet if the route to the destination is marked
|
||||||
* as local.
|
* as local.
|
||||||
*/
|
*/
|
||||||
if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL)) {
|
if (rt != NULL && ISSET(rt->rt_flags, RTF_LOCAL)) {
|
||||||
struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa);
|
struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa);
|
||||||
|
|
||||||
if (ip6_forwarding == 0 && rt->rt_ifidx != ifp->if_index &&
|
if (ip6_forwarding == 0 && rt->rt_ifidx != ifp->if_index &&
|
||||||
@ -617,14 +613,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
|||||||
}
|
}
|
||||||
#endif /* IPSEC */
|
#endif /* IPSEC */
|
||||||
|
|
||||||
ip6_forward(m, rt, pfrdr);
|
ip6_forward(m, &ro, pfrdr);
|
||||||
*mp = NULL;
|
*mp = NULL;
|
||||||
return IPPROTO_DONE;
|
return IPPROTO_DONE;
|
||||||
bad:
|
bad:
|
||||||
nxt = IPPROTO_DONE;
|
nxt = IPPROTO_DONE;
|
||||||
m_freemp(mp);
|
m_freemp(mp);
|
||||||
out:
|
out:
|
||||||
rtfree(rt);
|
rtfree(ro.ro_rt);
|
||||||
return nxt;
|
return nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ip6_output.c,v 1.289 2024/04/09 11:05:05 bluhm Exp $ */
|
/* $OpenBSD: ip6_output.c,v 1.290 2024/04/16 12:56:39 bluhm Exp $ */
|
||||||
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
|
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -391,7 +391,7 @@ reroute:
|
|||||||
/* initialize cached route */
|
/* initialize cached route */
|
||||||
if (ro == NULL) {
|
if (ro == NULL) {
|
||||||
ro = &iproute;
|
ro = &iproute;
|
||||||
bzero((caddr_t)ro, sizeof(*ro));
|
ro->ro_rt = NULL;
|
||||||
}
|
}
|
||||||
ro_pmtu = ro;
|
ro_pmtu = ro;
|
||||||
if (opt && opt->ip6po_rthdr)
|
if (opt && opt->ip6po_rthdr)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ip6_var.h,v 1.114 2024/02/14 13:18:21 claudio Exp $ */
|
/* $OpenBSD: ip6_var.h,v 1.115 2024/04/16 12:56:39 bluhm Exp $ */
|
||||||
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
|
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -320,7 +320,7 @@ int ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *,
|
|||||||
void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);
|
void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);
|
||||||
int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
|
int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
|
||||||
|
|
||||||
void ip6_forward(struct mbuf *, struct rtentry *, int);
|
void ip6_forward(struct mbuf *, struct route *, int);
|
||||||
|
|
||||||
void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *);
|
void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *);
|
||||||
int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int,
|
int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: raw_ip6.c,v 1.182 2024/02/13 12:22:09 bluhm Exp $ */
|
/* $OpenBSD: raw_ip6.c,v 1.183 2024/04/16 12:40:40 bluhm Exp $ */
|
||||||
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
|
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -155,9 +155,9 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
|
|||||||
} else
|
} else
|
||||||
rip6stat_inc(rip6s_ipackets);
|
rip6stat_inc(rip6s_ipackets);
|
||||||
|
|
||||||
bzero(&rip6src, sizeof(rip6src));
|
memset(&rip6src, 0, sizeof(rip6src));
|
||||||
rip6src.sin6_len = sizeof(struct sockaddr_in6);
|
|
||||||
rip6src.sin6_family = AF_INET6;
|
rip6src.sin6_family = AF_INET6;
|
||||||
|
rip6src.sin6_len = sizeof(rip6src);
|
||||||
/* KAME hack: recover scopeid */
|
/* KAME hack: recover scopeid */
|
||||||
in6_recoverscope(&rip6src, &ip6->ip6_src);
|
in6_recoverscope(&rip6src, &ip6->ip6_src);
|
||||||
|
|
||||||
@ -186,7 +186,13 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
|
|||||||
TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, inp_queue) {
|
TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, inp_queue) {
|
||||||
KASSERT(ISSET(inp->inp_flags, INP_IPV6));
|
KASSERT(ISSET(inp->inp_flags, INP_IPV6));
|
||||||
|
|
||||||
if (inp->inp_socket->so_rcv.sb_state & SS_CANTRCVMORE)
|
/*
|
||||||
|
* Packet must not be inserted after disconnected wakeup
|
||||||
|
* call. To avoid race, check again when holding receive
|
||||||
|
* buffer mutex.
|
||||||
|
*/
|
||||||
|
if (ISSET(READ_ONCE(inp->inp_socket->so_rcv.sb_state),
|
||||||
|
SS_CANTRCVMORE))
|
||||||
continue;
|
continue;
|
||||||
if (rtable_l2(inp->inp_rtableid) !=
|
if (rtable_l2(inp->inp_rtableid) !=
|
||||||
rtable_l2(m->m_pkthdr.ph_rtableid))
|
rtable_l2(m->m_pkthdr.ph_rtableid))
|
||||||
@ -264,7 +270,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
|
|||||||
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
|
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
|
||||||
if (n != NULL) {
|
if (n != NULL) {
|
||||||
struct socket *so = inp->inp_socket;
|
struct socket *so = inp->inp_socket;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if (inp->inp_flags & IN6P_CONTROLOPTS)
|
if (inp->inp_flags & IN6P_CONTROLOPTS)
|
||||||
ip6_savecontrol(inp, n, &opts);
|
ip6_savecontrol(inp, n, &opts);
|
||||||
@ -272,12 +278,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
|
|||||||
m_adj(n, *offp);
|
m_adj(n, *offp);
|
||||||
|
|
||||||
mtx_enter(&so->so_rcv.sb_mtx);
|
mtx_enter(&so->so_rcv.sb_mtx);
|
||||||
ret = sbappendaddr(so, &so->so_rcv,
|
if (!ISSET(inp->inp_socket->so_rcv.sb_state,
|
||||||
sin6tosa(&rip6src), n, opts);
|
SS_CANTRCVMORE)) {
|
||||||
|
ret = sbappendaddr(so, &so->so_rcv,
|
||||||
|
sin6tosa(&rip6src), n, opts);
|
||||||
|
}
|
||||||
mtx_leave(&so->so_rcv.sb_mtx);
|
mtx_leave(&so->so_rcv.sb_mtx);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* should notify about lost packet */
|
|
||||||
m_freem(n);
|
m_freem(n);
|
||||||
m_freem(opts);
|
m_freem(opts);
|
||||||
rip6stat_inc(rip6s_fullsock);
|
rip6stat_inc(rip6s_fullsock);
|
||||||
@ -727,7 +735,7 @@ rip6_disconnect(struct socket *so)
|
|||||||
if ((so->so_state & SS_ISCONNECTED) == 0)
|
if ((so->so_state & SS_ISCONNECTED) == 0)
|
||||||
return (ENOTCONN);
|
return (ENOTCONN);
|
||||||
|
|
||||||
so->so_state &= ~SS_ISCONNECTED; /* XXX */
|
soisdisconnected(so);
|
||||||
mtx_enter(&rawin6pcbtable.inpt_mtx);
|
mtx_enter(&rawin6pcbtable.inpt_mtx);
|
||||||
inp->inp_faddr6 = in6addr_any;
|
inp->inp_faddr6 = in6addr_any;
|
||||||
mtx_leave(&rawin6pcbtable.inpt_mtx);
|
mtx_leave(&rawin6pcbtable.inpt_mtx);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: mfs_vnops.c,v 1.60 2022/06/26 05:20:43 visa Exp $ */
|
/* $OpenBSD: mfs_vnops.c,v 1.61 2024/04/16 10:04:41 claudio Exp $ */
|
||||||
/* $NetBSD: mfs_vnops.c,v 1.8 1996/03/17 02:16:32 christos Exp $ */
|
/* $NetBSD: mfs_vnops.c,v 1.8 1996/03/17 02:16:32 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -237,6 +237,9 @@ mfs_reclaim(void *v)
|
|||||||
{
|
{
|
||||||
struct vop_reclaim_args *ap = v;
|
struct vop_reclaim_args *ap = v;
|
||||||
struct vnode *vp = ap->a_vp;
|
struct vnode *vp = ap->a_vp;
|
||||||
|
struct mfsnode *mfsp = VTOMFS(vp);
|
||||||
|
|
||||||
|
bufq_destroy(&mfsp->mfs_bufq);
|
||||||
|
|
||||||
free(vp->v_data, M_MFSNODE, sizeof(struct mfsnode));
|
free(vp->v_data, M_MFSNODE, sizeof(struct mfsnode));
|
||||||
vp->v_data = NULL;
|
vp->v_data = NULL;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: uvm_amap.c,v 1.92 2023/04/11 00:45:09 jsg Exp $ */
|
/* $OpenBSD: uvm_amap.c,v 1.93 2024/04/16 08:53:02 mpi Exp $ */
|
||||||
/* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */
|
/* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -662,9 +662,10 @@ amap_copy(struct vm_map *map, struct vm_map_entry *entry, int waitf,
|
|||||||
|
|
||||||
chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT);
|
chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT);
|
||||||
if (chunk == NULL) {
|
if (chunk == NULL) {
|
||||||
/* amap_wipeout() releases the lock. */
|
amap_unlock(srcamap);
|
||||||
amap->am_ref = 0;
|
/* Destroy the new amap. */
|
||||||
amap_wipeout(amap);
|
amap->am_ref--;
|
||||||
|
amap_free(amap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: uvm_swap.c,v 1.169 2024/02/03 18:51:59 beck Exp $ */
|
/* $OpenBSD: uvm_swap.c,v 1.170 2024/04/16 10:06:37 claudio Exp $ */
|
||||||
/* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */
|
/* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1088,6 +1088,7 @@ swap_off(struct proc *p, struct swapdev *sdp)
|
|||||||
*/
|
*/
|
||||||
if (sdp->swd_vp->v_type == VREG) {
|
if (sdp->swd_vp->v_type == VREG) {
|
||||||
crfree(sdp->swd_cred);
|
crfree(sdp->swd_cred);
|
||||||
|
bufq_destroy(&sdp->swd_bufq);
|
||||||
}
|
}
|
||||||
vrele(sdp->swd_vp);
|
vrele(sdp->swd_vp);
|
||||||
if (sdp->swd_vp != rootvp) {
|
if (sdp->swd_vp != rootvp) {
|
||||||
|
@ -378,85 +378,6 @@ bin_file(int f)
|
|||||||
return (bin_count > 5);
|
return (bin_count > 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Read a string from a file.
|
|
||||||
* Return a pointer to the string in memory.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
readfd(FILE *fd)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
int ch;
|
|
||||||
char *buf;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make a guess about how many chars in the string
|
|
||||||
* and allocate a buffer to hold it.
|
|
||||||
*/
|
|
||||||
len = 100;
|
|
||||||
buf = ecalloc(len, sizeof (char));
|
|
||||||
for (p = buf; ; p++) {
|
|
||||||
if ((ch = getc(fd)) == '\n' || ch == EOF)
|
|
||||||
break;
|
|
||||||
if (p >= buf + len-1) {
|
|
||||||
/*
|
|
||||||
* The string is too big to fit in the buffer we have.
|
|
||||||
* Allocate a new buffer, twice as big.
|
|
||||||
*/
|
|
||||||
len *= 2;
|
|
||||||
*p = '\0';
|
|
||||||
p = ecalloc(len, sizeof (char));
|
|
||||||
strlcpy(p, buf, len);
|
|
||||||
free(buf);
|
|
||||||
buf = p;
|
|
||||||
p = buf + strlen(buf);
|
|
||||||
}
|
|
||||||
*p = (char)ch;
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
return (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Execute a shell command.
|
|
||||||
* Return a pointer to a pipe connected to the shell command's standard output.
|
|
||||||
*/
|
|
||||||
static FILE *
|
|
||||||
shellcmd(char *cmd)
|
|
||||||
{
|
|
||||||
FILE *fd;
|
|
||||||
|
|
||||||
char *shell;
|
|
||||||
|
|
||||||
shell = lgetenv("SHELL");
|
|
||||||
if (shell != NULL && *shell != '\0') {
|
|
||||||
char *scmd;
|
|
||||||
char *esccmd;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read the output of <$SHELL -c cmd>.
|
|
||||||
* Escape any metacharacters in the command.
|
|
||||||
*/
|
|
||||||
esccmd = shell_quote(cmd);
|
|
||||||
if (esccmd == NULL) {
|
|
||||||
fd = popen(cmd, "r");
|
|
||||||
} else {
|
|
||||||
scmd = easprintf("%s -c %s", shell, esccmd);
|
|
||||||
free(esccmd);
|
|
||||||
fd = popen(scmd, "r");
|
|
||||||
free(scmd);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fd = popen(cmd, "r");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Redirection in `popen' might have messed with the
|
|
||||||
* standard devices. Restore binary input mode.
|
|
||||||
*/
|
|
||||||
return (fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expand a filename, doing any system-specific metacharacter substitutions.
|
* Expand a filename, doing any system-specific metacharacter substitutions.
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: req.c,v 1.28 2023/07/02 07:05:14 tb Exp $ */
|
/* $OpenBSD: req.c,v 1.29 2024/04/17 01:24:43 tb Exp $ */
|
||||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -1697,6 +1697,7 @@ set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
|
|||||||
if (EVP_PKEY_keygen_init(gctx) <= 0) {
|
if (EVP_PKEY_keygen_init(gctx) <= 0) {
|
||||||
BIO_puts(err, "Error initializing keygen context\n");
|
BIO_puts(err, "Error initializing keygen context\n");
|
||||||
ERR_print_errors(err);
|
ERR_print_errors(err);
|
||||||
|
EVP_PKEY_CTX_free(gctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
|
if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: server_file.c,v 1.78 2024/01/06 11:29:00 espie Exp $ */
|
/* $OpenBSD: server_file.c,v 1.79 2024/04/16 17:15:50 florian Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 - 2017 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2006 - 2017 Reyk Floeter <reyk@openbsd.org>
|
||||||
@ -43,12 +43,14 @@
|
|||||||
int server_file_access(struct httpd *, struct client *,
|
int server_file_access(struct httpd *, struct client *,
|
||||||
char *, size_t);
|
char *, size_t);
|
||||||
int server_file_request(struct httpd *, struct client *,
|
int server_file_request(struct httpd *, struct client *,
|
||||||
char *, struct timespec *);
|
struct media_type *, int, const struct stat *);
|
||||||
int server_partial_file_request(struct httpd *, struct client *,
|
int server_partial_file_request(struct httpd *, struct client *,
|
||||||
char *, struct timespec *, char *);
|
struct media_type *, int, const struct stat *,
|
||||||
int server_file_index(struct httpd *, struct client *);
|
char *);
|
||||||
|
int server_file_index(struct httpd *, struct client *, int,
|
||||||
|
struct stat *);
|
||||||
int server_file_modified_since(struct http_descriptor *,
|
int server_file_modified_since(struct http_descriptor *,
|
||||||
struct timespec *);
|
const struct timespec *);
|
||||||
int server_file_method(struct client *);
|
int server_file_method(struct client *);
|
||||||
int parse_range_spec(char *, size_t, struct range *);
|
int parse_range_spec(char *, size_t, struct range *);
|
||||||
int parse_ranges(struct client *, char *, size_t);
|
int parse_ranges(struct client *, char *, size_t);
|
||||||
@ -62,28 +64,42 @@ server_file_access(struct httpd *env, struct client *clt,
|
|||||||
struct server_config *srv_conf = clt->clt_srv_conf;
|
struct server_config *srv_conf = clt->clt_srv_conf;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct kv *r, key;
|
struct kv *r, key;
|
||||||
|
struct media_type *media;
|
||||||
char *newpath, *encodedpath;
|
char *newpath, *encodedpath;
|
||||||
int ret;
|
int ret, fd;
|
||||||
|
|
||||||
errno = 0;
|
if ((fd = open(path, O_RDONLY)) == -1) {
|
||||||
|
switch (errno) {
|
||||||
|
case ENOENT:
|
||||||
|
case ENOTDIR:
|
||||||
|
return (404);
|
||||||
|
case EACCES:
|
||||||
|
return (403);
|
||||||
|
default:
|
||||||
|
return (500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fstat(fd, &st) == -1) {
|
||||||
|
close(fd);
|
||||||
|
return (500);
|
||||||
|
}
|
||||||
|
|
||||||
if (stat(path, &st) == -1) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
goto fail;
|
|
||||||
} else if (S_ISDIR(st.st_mode)) {
|
|
||||||
/* Deny access if directory indexing is disabled */
|
/* Deny access if directory indexing is disabled */
|
||||||
if (srv_conf->flags & SRVFLAG_NO_INDEX) {
|
if (srv_conf->flags & SRVFLAG_NO_INDEX) {
|
||||||
errno = EACCES;
|
close(fd);
|
||||||
goto fail;
|
return (403);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc->http_path_alias != NULL) {
|
if (desc->http_path_alias != NULL) {
|
||||||
/* Recursion - the index "file" is a directory? */
|
/* Recursion - the index "file" is a directory? */
|
||||||
errno = EINVAL;
|
close(fd);
|
||||||
goto fail;
|
return (500);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redirect to path with trailing "/" */
|
/* Redirect to path with trailing "/" */
|
||||||
if (path[strlen(path) - 1] != '/') {
|
if (path[strlen(path) - 1] != '/') {
|
||||||
|
close(fd);
|
||||||
if ((encodedpath = url_encode(desc->http_path)) == NULL)
|
if ((encodedpath = url_encode(desc->http_path)) == NULL)
|
||||||
return (500);
|
return (500);
|
||||||
if (asprintf(&newpath, "%s/", encodedpath) == -1) {
|
if (asprintf(&newpath, "%s/", encodedpath) == -1) {
|
||||||
@ -101,18 +117,21 @@ server_file_access(struct httpd *env, struct client *clt,
|
|||||||
|
|
||||||
/* Append the default index file to the location */
|
/* Append the default index file to the location */
|
||||||
if (asprintf(&newpath, "%s%s", desc->http_path,
|
if (asprintf(&newpath, "%s%s", desc->http_path,
|
||||||
srv_conf->index) == -1)
|
srv_conf->index) == -1) {
|
||||||
|
close(fd);
|
||||||
return (500);
|
return (500);
|
||||||
|
}
|
||||||
desc->http_path_alias = newpath;
|
desc->http_path_alias = newpath;
|
||||||
if (server_getlocation(clt, newpath) != srv_conf) {
|
if (server_getlocation(clt, newpath) != srv_conf) {
|
||||||
/* The location has changed */
|
/* The location has changed */
|
||||||
|
close(fd);
|
||||||
return (server_file(env, clt));
|
return (server_file(env, clt));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise append the default index file to the path */
|
/* Otherwise append the default index file to the path */
|
||||||
if (strlcat(path, srv_conf->index, len) >= len) {
|
if (strlcat(path, srv_conf->index, len) >= len) {
|
||||||
errno = EACCES;
|
close(fd);
|
||||||
goto fail;
|
return (403);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = server_file_access(env, clt, path, len);
|
ret = server_file_access(env, clt, path, len);
|
||||||
@ -124,39 +143,72 @@ server_file_access(struct httpd *env, struct client *clt,
|
|||||||
* stat.
|
* stat.
|
||||||
*/
|
*/
|
||||||
if ((srv_conf->flags & SRVFLAG_AUTO_INDEX) == 0) {
|
if ((srv_conf->flags & SRVFLAG_AUTO_INDEX) == 0) {
|
||||||
errno = EACCES;
|
close(fd);
|
||||||
goto fail;
|
return (403);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (server_file_index(env, clt));
|
return (server_file_index(env, clt, fd, &st));
|
||||||
}
|
}
|
||||||
|
close(fd);
|
||||||
return (ret);
|
return (ret);
|
||||||
} else if (!S_ISREG(st.st_mode)) {
|
} else if (!S_ISREG(st.st_mode)) {
|
||||||
/* Don't follow symlinks and ignore special files */
|
/* Don't follow symlinks and ignore special files */
|
||||||
errno = EACCES;
|
close(fd);
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
key.kv_key = "Range";
|
|
||||||
r = kv_find(&desc->http_headers, &key);
|
|
||||||
if (r != NULL)
|
|
||||||
return (server_partial_file_request(env, clt, path,
|
|
||||||
&st.st_mtim, r->kv_value));
|
|
||||||
else
|
|
||||||
return (server_file_request(env, clt, path, &st.st_mtim));
|
|
||||||
|
|
||||||
fail:
|
|
||||||
switch (errno) {
|
|
||||||
case ENOENT:
|
|
||||||
case ENOTDIR:
|
|
||||||
return (404);
|
|
||||||
case EACCES:
|
|
||||||
return (403);
|
return (403);
|
||||||
default:
|
|
||||||
return (500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTREACHED */
|
media = media_find_config(env, srv_conf, path);
|
||||||
|
|
||||||
|
/* Only consider range requests for GET */
|
||||||
|
if (desc->http_method == HTTP_METHOD_GET) {
|
||||||
|
key.kv_key = "Range";
|
||||||
|
r = kv_find(&desc->http_headers, &key);
|
||||||
|
if (r != NULL)
|
||||||
|
return (server_partial_file_request(env, clt, media,
|
||||||
|
fd, &st, r->kv_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* change path to path.gz if necessary. */
|
||||||
|
if (srv_conf->flags & SRVFLAG_GZIP_STATIC) {
|
||||||
|
struct http_descriptor *req = clt->clt_descreq;
|
||||||
|
struct http_descriptor *resp = clt->clt_descresp;
|
||||||
|
struct stat gzst;
|
||||||
|
int gzfd;
|
||||||
|
char gzpath[PATH_MAX];
|
||||||
|
|
||||||
|
/* check Accept-Encoding header */
|
||||||
|
key.kv_key = "Accept-Encoding";
|
||||||
|
r = kv_find(&req->http_headers, &key);
|
||||||
|
|
||||||
|
if (r != NULL && strstr(r->kv_value, "gzip") != NULL) {
|
||||||
|
/* append ".gz" to path and check existence */
|
||||||
|
ret = snprintf(gzpath, sizeof(gzpath), "%s.gz", path);
|
||||||
|
if (ret < 0 || (size_t)ret >= sizeof(gzpath)) {
|
||||||
|
close(fd);
|
||||||
|
return (500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((gzfd = open(gzpath, O_RDONLY)) != -1) {
|
||||||
|
/* .gz must be a file, and not older */
|
||||||
|
if (fstat(gzfd, &gzst) != -1 &&
|
||||||
|
S_ISREG(gzst.st_mode) &&
|
||||||
|
timespeccmp(&gzst.st_mtim, &st.st_mtim,
|
||||||
|
>=)) {
|
||||||
|
kv_add(&resp->http_headers,
|
||||||
|
"Content-Encoding", "gzip");
|
||||||
|
/* Use original file timestamp */
|
||||||
|
gzst.st_mtim = st.st_mtim;
|
||||||
|
st = gzst;
|
||||||
|
close(fd);
|
||||||
|
fd = gzfd;
|
||||||
|
} else {
|
||||||
|
close(gzfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (server_file_request(env, clt, media, fd, &st));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -216,73 +268,30 @@ server_file_method(struct client *clt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
server_file_request(struct httpd *env, struct client *clt, char *path,
|
server_file_request(struct httpd *env, struct client *clt, struct media_type
|
||||||
struct timespec *mtim)
|
*media, int fd, const struct stat *st)
|
||||||
{
|
{
|
||||||
struct server_config *srv_conf = clt->clt_srv_conf;
|
struct server_config *srv_conf = clt->clt_srv_conf;
|
||||||
struct media_type *media;
|
|
||||||
const char *errstr = NULL;
|
const char *errstr = NULL;
|
||||||
int fd = -1, ret, code = 500;
|
int ret, code = 500;
|
||||||
struct stat st;
|
|
||||||
size_t bufsiz;
|
size_t bufsiz;
|
||||||
char gzpath[PATH_MAX];
|
|
||||||
|
|
||||||
if ((ret = server_file_method(clt)) != 0) {
|
if ((ret = server_file_method(clt)) != 0) {
|
||||||
code = ret;
|
code = ret;
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
media = media_find_config(env, srv_conf, path);
|
if ((ret = server_file_modified_since(clt->clt_descreq, &st->st_mtim))
|
||||||
if ((ret = server_file_modified_since(clt->clt_descreq, mtim)) != -1) {
|
!= -1) {
|
||||||
/* send the header without a body */
|
/* send the header without a body */
|
||||||
if ((ret = server_response_http(clt, ret, media, -1,
|
if ((ret = server_response_http(clt, ret, media, -1,
|
||||||
MINIMUM(time(NULL), mtim->tv_sec))) == -1)
|
MINIMUM(time(NULL), st->st_mtim.tv_sec))) == -1)
|
||||||
goto fail;
|
goto fail;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change path to path.gz if necessary. */
|
ret = server_response_http(clt, 200, media, st->st_size,
|
||||||
if (srv_conf->flags & SRVFLAG_GZIP_STATIC) {
|
MINIMUM(time(NULL), st->st_mtim.tv_sec));
|
||||||
struct http_descriptor *req = clt->clt_descreq;
|
|
||||||
struct http_descriptor *resp = clt->clt_descresp;
|
|
||||||
struct kv *r, key;
|
|
||||||
|
|
||||||
/* check Accept-Encoding header */
|
|
||||||
key.kv_key = "Accept-Encoding";
|
|
||||||
r = kv_find(&req->http_headers, &key);
|
|
||||||
|
|
||||||
if (r != NULL && strstr(r->kv_value, "gzip") != NULL) {
|
|
||||||
/* append ".gz" to path and check existence */
|
|
||||||
ret = snprintf(gzpath, sizeof(gzpath), "%s.gz", path);
|
|
||||||
if (ret < 0 || (size_t)ret >= sizeof(gzpath))
|
|
||||||
goto abort;
|
|
||||||
if ((fd = open(gzpath, O_RDONLY)) != -1) {
|
|
||||||
/* .gz must be a file, and not older */
|
|
||||||
if (fstat(fd, &st) != -1 &&
|
|
||||||
S_ISREG(st.st_mode) &&
|
|
||||||
timespeccmp(&st.st_mtim, mtim, >=)) {
|
|
||||||
kv_add(&resp->http_headers,
|
|
||||||
"Content-Encoding", "gzip");
|
|
||||||
/* Use original file timestamp */
|
|
||||||
st.st_mtim = *mtim;
|
|
||||||
} else {
|
|
||||||
close(fd);
|
|
||||||
fd = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now open the file, should be readable or we have another problem */
|
|
||||||
if (fd == -1) {
|
|
||||||
if ((fd = open(path, O_RDONLY)) == -1)
|
|
||||||
goto abort;
|
|
||||||
if (fstat(fd, &st) == -1)
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = server_response_http(clt, 200, media, st.st_size,
|
|
||||||
MINIMUM(time(NULL), st.st_mtim.tv_sec));
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case -1:
|
case -1:
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -307,7 +316,7 @@ server_file_request(struct httpd *env, struct client *clt, char *path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust read watermark to the optimal file io size */
|
/* Adjust read watermark to the optimal file io size */
|
||||||
bufsiz = MAXIMUM(st.st_blksize, 64 * 1024);
|
bufsiz = MAXIMUM(st->st_blksize, 64 * 1024);
|
||||||
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
|
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
|
||||||
bufsiz);
|
bufsiz);
|
||||||
|
|
||||||
@ -333,47 +342,34 @@ server_file_request(struct httpd *env, struct client *clt, char *path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
server_partial_file_request(struct httpd *env, struct client *clt, char *path,
|
server_partial_file_request(struct httpd *env, struct client *clt,
|
||||||
struct timespec *mtim, char *range_str)
|
struct media_type *media, int fd, const struct stat *st, char *range_str)
|
||||||
{
|
{
|
||||||
struct server_config *srv_conf = clt->clt_srv_conf;
|
struct server_config *srv_conf = clt->clt_srv_conf;
|
||||||
struct http_descriptor *resp = clt->clt_descresp;
|
struct http_descriptor *resp = clt->clt_descresp;
|
||||||
struct http_descriptor *desc = clt->clt_descreq;
|
struct media_type multipart_media;
|
||||||
struct media_type *media, multipart_media;
|
|
||||||
struct range_data *r = &clt->clt_ranges;
|
struct range_data *r = &clt->clt_ranges;
|
||||||
struct range *range;
|
struct range *range;
|
||||||
size_t content_length = 0, bufsiz;
|
size_t content_length = 0, bufsiz;
|
||||||
struct stat st;
|
int code = 500, i, nranges, ret;
|
||||||
int code = 500, fd = -1, i, nranges, ret;
|
|
||||||
char content_range[64];
|
char content_range[64];
|
||||||
const char *errstr = NULL;
|
const char *errstr = NULL;
|
||||||
|
|
||||||
/* Ignore range request for methods other than GET */
|
if ((nranges = parse_ranges(clt, range_str, st->st_size)) < 1) {
|
||||||
if (desc->http_method != HTTP_METHOD_GET)
|
|
||||||
return server_file_request(env, clt, path, mtim);
|
|
||||||
|
|
||||||
/* Now open the file, should be readable or we have another problem */
|
|
||||||
if ((fd = open(path, O_RDONLY)) == -1)
|
|
||||||
goto abort;
|
|
||||||
if (fstat(fd, &st) == -1)
|
|
||||||
goto abort;
|
|
||||||
|
|
||||||
if ((nranges = parse_ranges(clt, range_str, st.st_size)) < 1) {
|
|
||||||
code = 416;
|
code = 416;
|
||||||
(void)snprintf(content_range, sizeof(content_range),
|
(void)snprintf(content_range, sizeof(content_range),
|
||||||
"bytes */%lld", st.st_size);
|
"bytes */%lld", st->st_size);
|
||||||
errstr = content_range;
|
errstr = content_range;
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
media = media_find_config(env, srv_conf, path);
|
|
||||||
r->range_media = media;
|
r->range_media = media;
|
||||||
|
|
||||||
if (nranges == 1) {
|
if (nranges == 1) {
|
||||||
range = &r->range[0];
|
range = &r->range[0];
|
||||||
(void)snprintf(content_range, sizeof(content_range),
|
(void)snprintf(content_range, sizeof(content_range),
|
||||||
"bytes %lld-%lld/%lld", range->start, range->end,
|
"bytes %lld-%lld/%lld", range->start, range->end,
|
||||||
st.st_size);
|
st->st_size);
|
||||||
if (kv_add(&resp->http_headers, "Content-Range",
|
if (kv_add(&resp->http_headers, "Content-Range",
|
||||||
content_range) == NULL)
|
content_range) == NULL)
|
||||||
goto abort;
|
goto abort;
|
||||||
@ -395,7 +391,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
|
|||||||
"Content-Range: bytes %lld-%lld/%lld\r\n\r\n",
|
"Content-Range: bytes %lld-%lld/%lld\r\n\r\n",
|
||||||
clt->clt_boundary,
|
clt->clt_boundary,
|
||||||
media->media_type, media->media_subtype,
|
media->media_type, media->media_subtype,
|
||||||
range->start, range->end, st.st_size)) < 0)
|
range->start, range->end, st->st_size)) < 0)
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
/* Add data length */
|
/* Add data length */
|
||||||
@ -420,7 +416,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
|
|||||||
r->range_toread = TOREAD_HTTP_RANGE;
|
r->range_toread = TOREAD_HTTP_RANGE;
|
||||||
|
|
||||||
ret = server_response_http(clt, 206, media, content_length,
|
ret = server_response_http(clt, 206, media, content_length,
|
||||||
MINIMUM(time(NULL), st.st_mtim.tv_sec));
|
MINIMUM(time(NULL), st->st_mtim.tv_sec));
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case -1:
|
case -1:
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -445,7 +441,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust read watermark to the optimal file io size */
|
/* Adjust read watermark to the optimal file io size */
|
||||||
bufsiz = MAXIMUM(st.st_blksize, 64 * 1024);
|
bufsiz = MAXIMUM(st->st_blksize, 64 * 1024);
|
||||||
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
|
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
|
||||||
bufsiz);
|
bufsiz);
|
||||||
|
|
||||||
@ -482,21 +478,21 @@ select_visible(const struct dirent *dp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
server_file_index(struct httpd *env, struct client *clt)
|
server_file_index(struct httpd *env, struct client *clt, int fd,
|
||||||
|
struct stat *st)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
char tmstr[21];
|
char tmstr[21];
|
||||||
struct http_descriptor *desc = clt->clt_descreq;
|
struct http_descriptor *desc = clt->clt_descreq;
|
||||||
struct server_config *srv_conf = clt->clt_srv_conf;
|
struct server_config *srv_conf = clt->clt_srv_conf;
|
||||||
struct dirent **namelist, *dp;
|
struct dirent **namelist, *dp;
|
||||||
int namesize, i, ret, fd = -1, skip;
|
int namesize, i, ret, skip;
|
||||||
int code = 500;
|
int code = 500;
|
||||||
struct evbuffer *evb = NULL;
|
struct evbuffer *evb = NULL;
|
||||||
struct media_type *media;
|
struct media_type *media;
|
||||||
const char *stripped;
|
const char *stripped;
|
||||||
char *escapeduri, *escapedhtml, *escapedpath;
|
char *escapeduri, *escapedhtml, *escapedpath;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
struct stat st;
|
|
||||||
time_t t, dir_mtime;
|
time_t t, dir_mtime;
|
||||||
char human_size[FMT_SCALED_STRSIZE];
|
char human_size[FMT_SCALED_STRSIZE];
|
||||||
|
|
||||||
@ -511,14 +507,8 @@ server_file_index(struct httpd *env, struct client *clt)
|
|||||||
srv_conf->root, stripped) >= sizeof(path))
|
srv_conf->root, stripped) >= sizeof(path))
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
/* Now open the file, should be readable or we have another problem */
|
|
||||||
if ((fd = open(path, O_RDONLY)) == -1)
|
|
||||||
goto abort;
|
|
||||||
if (fstat(fd, &st) == -1)
|
|
||||||
goto abort;
|
|
||||||
|
|
||||||
/* Save last modification time */
|
/* Save last modification time */
|
||||||
dir_mtime = MINIMUM(time(NULL), st.st_mtim.tv_sec);
|
dir_mtime = MINIMUM(time(NULL), st->st_mtim.tv_sec);
|
||||||
|
|
||||||
if ((evb = evbuffer_new()) == NULL)
|
if ((evb = evbuffer_new()) == NULL)
|
||||||
goto abort;
|
goto abort;
|
||||||
@ -548,7 +538,7 @@ server_file_index(struct httpd *env, struct client *clt)
|
|||||||
|
|
||||||
free(escapedpath);
|
free(escapedpath);
|
||||||
|
|
||||||
if ((namesize = scandir(path, &namelist, select_visible,
|
if ((namesize = scandirat(fd, ".", &namelist, select_visible,
|
||||||
alphasort)) == -1)
|
alphasort)) == -1)
|
||||||
goto abort;
|
goto abort;
|
||||||
|
|
||||||
@ -722,7 +712,8 @@ server_file_error(struct bufferevent *bev, short error, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
server_file_modified_since(struct http_descriptor *desc, struct timespec *mtim)
|
server_file_modified_since(struct http_descriptor *desc, const struct timespec
|
||||||
|
*mtim)
|
||||||
{
|
{
|
||||||
struct kv key, *since;
|
struct kv key, *since;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
Loading…
Reference in New Issue
Block a user