This should be the best compromise without overcomplicating our
patches.
Aisha
diff --git a/net/usockets/Makefile b/net/usockets/Makefile
index a484c23f93a..865795d0e1e 100644
--- a/net/usockets/Makefile
+++ b/net/usockets/Makefile
@@ -3,38 +3,29 @@
COMMENT = eventing, networking & crypto for async applications
CATEGORIES = net
-VERSION = 0.6.0
-REVISION = 1
-
-DISTNAME = usockets-${VERSION}
-PKGNAME = ${DISTNAME:L}
-
-SHARED_LIBS = usockets 1.0
+SHARED_LIBS = usockets 2.0
GH_ACCOUNT = uNetworking
GH_PROJECT = uSockets
-#GH_TAGNAME = v0.6.0
-# cstdlib include error
-GH_COMMIT = 7683672d87067cd75b854f4e36b9820f4809a4be
-
+GH_TAGNAME = v0.8.1
+PKGNAME = ${DISTNAME:L}
MAINTAINER = Aisha Tammy <open...@aisha.cc>
# Apache 2.0
PERMIT_PACKAGE = Yes
-WANTLIB += ${COMPILER_LIBCXX} crypto ssl uv
+WANTLIB += ${COMPILER_LIBCXX} crypto ssl uv
# C11 C++17
COMPILER = base-clang ports-gcc
LIB_DEPENDS = devel/libuv
-USE_GMAKE = Yes
-MAKE_FLAGS = CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" \
- CC="${CC}" CXX="${CXX}" \
- LIBusockets_VERSION="${LIBusockets_VERSION}"
+MAKE_FILE = Makefile.obsd
+
+MAKE_ENV = LIBusockets_VERSION="${LIBusockets_VERSION}"
-NO_TEST = Yes
+# tests need A LOT of file desrciptors ~5000-6000
.include <bsd.port.mk>
diff --git a/net/usockets/distinfo b/net/usockets/distinfo
index 964ba508e9e..a437989a34e 100644
--- a/net/usockets/distinfo
+++ b/net/usockets/distinfo
@@ -1,2 +1,2 @@
-SHA256 (usockets-0.6.0-7683672d.tar.gz) =
0OooGCHD8ezNIcaB1zDPK6RQLGGYGZJb24Vemjlat7c=
-SIZE (usockets-0.6.0-7683672d.tar.gz) = 57634
+SHA256 (uSockets-0.8.1.tar.gz) = OzO1kkqSV3hU4jJrPi05OEnsAL64ZaEnG/JMDyEMwdY=
+SIZE (uSockets-0.8.1.tar.gz) = 65470
diff --git a/net/usockets/patches/patch-Makefile
b/net/usockets/patches/patch-Makefile
deleted file mode 100644
index e718b65a265..00000000000
--- a/net/usockets/patches/patch-Makefile
+++ /dev/null
@@ -1,98 +0,0 @@
-$OpenBSD: patch-Makefile,v 1.3 2020/12/11 22:33:22 sthen Exp $
-
-add shared + static lib + pkg-config file
-remove -flto -O3
-
-Index: Makefile
---- Makefile.orig
-+++ Makefile
-@@ -1,60 +1,40 @@
--# WITH_OPENSSL=1 enables OpenSSL 1.1+ support or BoringSSL
--# For now we need to link with C++ for OpenSSL support, but should be removed
with time
--ifeq ($(WITH_OPENSSL),1)
-- override CFLAGS += -DLIBUS_USE_OPENSSL
-- # With problems on macOS, make sure to pass needed LDFLAGS required to
find these
-- override LDFLAGS += -lssl -lcrypto -lstdc++
--else
-- # WITH_WOLFSSL=1 enables WolfSSL 4.2.0 support (mutually exclusive with
OpenSSL)
-- ifeq ($(WITH_WOLFSSL),1)
-- # todo: change these
-- override CFLAGS += -DLIBUS_USE_WOLFSSL -I/usr/local/include
-- override LDFLAGS += -L/usr/local/lib -lwolfssl
-- else
-- override CFLAGS += -DLIBUS_NO_SSL
-- endif
--endif
-+DESTDIR ?=
-
--# WITH_LIBUV=1 builds with libuv as event-loop
--ifeq ($(WITH_LIBUV),1)
-- override CFLAGS += -DLIBUS_USE_LIBUV
-- override LDFLAGS += -luv
--endif
-+PREFIX ?= "/usr/local"
-+LIBDIR ?= "$(PREFIX)/lib"
-+INCLUDEDIR ?= "$(PREFIX)/include"
-
--# WITH_GCD=1 builds with libdispatch as event-loop
--ifeq ($(WITH_GCD),1)
-- override CFLAGS += -DLIBUS_USE_GCD
-- override LDFLAGS += -framework CoreFoundation
--endif
-+# OpenBSD specific library version
-+LIBTARGET ?= libusockets.so.$(LIBusockets_VERSION)
-
--# WITH_ASAN builds with sanitizers
--ifeq ($(WITH_ASAN),1)
-- override CFLAGS += -fsanitize=address -g
-- override LDFLAGS += -lasan
--endif
-+PKG_CONFIG ?= pkg-config
-
--override CFLAGS += -std=c11 -Isrc
--override LDFLAGS += uSockets.a
-+override LDFLAGS += -lstdc++ -lcrypto -lssl `$(PKG_CONFIG) --libs libuv`
-
--# By default we build the uSockets.a static library
--default:
-- rm -f *.o
-- $(CC) $(CFLAGS) -flto -O3 -c src/*.c src/eventing/*.c src/crypto/*.c
--# For now we do rely on C++17 for OpenSSL support but we will be porting this
work to C11
--ifeq ($(WITH_OPENSSL),1)
-- $(CXX) $(CXXFLAGS) -std=c++17 -flto -O3 -c src/crypto/*.cpp
--endif
-- $(AR) rvs uSockets.a *.o
-+COMMON_FLAGS = -DLIBUS_USE_OPENSSL -DLIBUS_USE_LIBUV -Isrc
`$(PKG_CONFIG) --cflags libuv`
-+override CFLAGS += $(COMMON_FLAGS)
-+override CXXFLAGS += $(COMMON_FLAGS)
-
--# Builds all examples
--.PHONY: examples
--examples: default
-- for f in examples/*.c; do $(CC) -flto -O3 $(CFLAGS) -o $$(basename "$$f" ".c")
"$$f" $(LDFLAGS); done
-+all:
-+ $(CC) -std=c11 -fPIC $(CFLAGS) -c src/*.c src/eventing/*.c
src/crypto/*.c
-+ $(CXX) -std=c++17 -fPIC $(CXXFLAGS) -c src/crypto/*.cpp
-+ $(AR) rvs libusockets.a *.o
-+ $(CC) -shared -o $(LIBTARGET) *.o -Wl,-soname,$(LIBTARGET) $(LDFLAGS)
-+ sed -e "s:@PREFIX@:$(PREFIX):" -e "s:@VERSION@:$(LIBusockets_VERSION):"
\
-+ libusockets.pc.in > libusockets.pc
-
--swift_examples:
-- swiftc -O -I . examples/swift_http_server/main.swift uSockets.a -o
swift_http_server
-+install:
-+ install -d "$(LIBDIR)/pkgconfig" "$(INCLUDEDIR)"
-+ install -m 644 src/libusockets.h "$(INCLUDEDIR)"
-+ install -m 755 $(LIBTARGET) "$(LIBDIR)"
-+ install -m 755 libusockets.a "$(LIBDIR)"
-+ install -m 644 libusockets.pc "$(LIBDIR)/pkgconfig"
-
- clean:
- rm -f *.o
- rm -f *.a
-- rm -rf .certs
-+ rm -f *.so
-+ rm -f libusockets.pc
-+
-+.PHONY: all install clean
-+
diff --git a/net/usockets/patches/patch-Makefile_obsd
b/net/usockets/patches/patch-Makefile_obsd
new file mode 100644
index 00000000000..d822e7933ae
--- /dev/null
+++ b/net/usockets/patches/patch-Makefile_obsd
@@ -0,0 +1,42 @@
+$OpenBSD$
+
+Index: Makefile.obsd
+--- Makefile.obsd.orig
++++ Makefile.obsd
+@@ -0,0 +1,36 @@
++PREFIX ?= /usr/local
++LIBDIR ?= "$(PREFIX)/lib"
++INCLUDEDIR ?= "$(PREFIX)/include"
++
++PKG_CONFIG ?= pkg-config
++
++LIBTARGET = libusockets.so.$(LIBusockets_VERSION)
++
++REQUIRES = libcrypto libssl libuv
++COMMON_FLAGS = -Isrc -DLIBUS_USE_OPENSSL -DLIBUS_USE_LIBUV
`$(PKG_CONFIG) --cflags $(REQUIRES)`
++
++CFLAGS += -std=c11 -fPIC $(COMMON_FLAGS)
++CXXFLAGS += -std=c++17 -fPIC $(COMMON_FLAGS)
++LDFLAGS += `$(PKG_CONFIG) --libs $(REQUIRES)`
++
++all:
++ $(CC) $(CFLAGS) -c src/*.c src/eventing/*.c src/crypto/*.c
++ $(CXX) $(CXXFLAGS) -c src/crypto/*.cpp
++ $(AR) rvs libusockets.a *.o
++ $(CXX) $(CXXFLAGS) -shared -o $(LIBTARGET) *.o -Wl,-soname,$(LIBTARGET)
$(LDFLAGS)
++ sed -e "s:@PREFIX@:$(PREFIX):" -e "s:@VERSION@:$(LIBusockets_VERSION):"
libusockets.pc.in > libusockets.pc
++
++install:
++ install -d "$(LIBDIR)/pkgconfig" "$(INCLUDEDIR)"
++ install -m 644 src/libusockets.h "$(INCLUDEDIR)/"
++ install -m 644 $(LIBTARGET) "$(LIBDIR)/"
++ install -m 644 libusockets.a "$(LIBDIR)/"
++ install -m 644 libusockets.pc "$(LIBDIR)/pkgconfig/"
++
++test:
++ rm -f localhost.pem localhost.crt
++ openssl req -x509 -out localhost.crt -keyout localhost.pem -newkey
rsa:2048 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config
localhost.conf
++ $(CXX) $(CXXFLAGS) libusockets.a examples/hammer_test.c -o hammer_test
$(LDFLAGS)
++ ./hammer_test
++
++.PHONY: all install test
diff --git a/net/usockets/patches/patch-examples_hammer_test_c
b/net/usockets/patches/patch-examples_hammer_test_c
new file mode 100644
index 00000000000..ebebc35abaf
--- /dev/null
+++ b/net/usockets/patches/patch-examples_hammer_test_c
@@ -0,0 +1,17 @@
+$OpenBSD$
+
+Index: examples/hammer_test.c
+--- examples/hammer_test.c.orig
++++ examples/hammer_test.c
+@@ -403,9 +403,8 @@ int main() {
+
+ // these are ignored for non-SSL
+ struct us_socket_context_options_t options = {};
+- options.key_file_name = "/home/alexhultman/uWebSockets.js/misc/key.pem";
+- options.cert_file_name = "/home/alexhultman/uWebSockets.js/misc/cert.pem";
+- options.passphrase = "1234";
++ options.key_file_name = "localhost.pem";
++ options.cert_file_name = "localhost.crt";
+
+ http_context = us_create_socket_context(SSL, loop, sizeof(struct
http_context), options);
+
diff --git a/net/usockets/patches/patch-libusockets_pc_in
b/net/usockets/patches/patch-libusockets_pc_in
index 363646177e9..37a2632a788 100644
--- a/net/usockets/patches/patch-libusockets_pc_in
+++ b/net/usockets/patches/patch-libusockets_pc_in
@@ -1,9 +1,9 @@
-$OpenBSD: patch-libusockets_pc_in,v 1.1 2020/12/11 22:34:51 sthen Exp $
+$OpenBSD$
Index: libusockets.pc.in
--- libusockets.pc.in.orig
+++ libusockets.pc.in
-@@ -0,0 +1,14 @@
+@@ -0,0 +1,13 @@
+prefix=@PREFIX@
+libdir=${prefix}/lib
+includedir=${prefix}/include
@@ -17,4 +17,3 @@ Index: libusockets.pc.in
+Libs: -L${libdir} -lusockets
+Libs.private: -lcrypto -lssl
+Requires.private: libuv
-+
diff --git a/net/usockets/patches/patch-localhost_conf
b/net/usockets/patches/patch-localhost_conf
new file mode 100644
index 00000000000..76233fbb2f0
--- /dev/null
+++ b/net/usockets/patches/patch-localhost_conf
@@ -0,0 +1,14 @@
+$OpenBSD$
+
+Index: localhost.conf
+--- localhost.conf.orig
++++ localhost.conf
+@@ -0,0 +1,8 @@
++[dn]
++CN=localhost
++[req]
++distinguished_name = dn
++[EXT]
++subjectAltName=DNS:localhost
++keyUsage=digitalSignature
++extendedKeyUsage=serverAuth
diff --git a/www/purritobin/Makefile b/www/purritobin/Makefile
index 698ca75c722..b0d47f8e55f 100644
--- a/www/purritobin/Makefile
+++ b/www/purritobin/Makefile
@@ -1,12 +1,12 @@
# $OpenBSD $
COMMENT = minimalistic command line pastebin
-PKGNAME = ${DISTNAME:L}
CATEGORIES = www net
GH_ACCOUNT = PurritoBin
GH_PROJECT = PurritoBin
-GH_TAGNAME = 0.3.3
+GH_TAGNAME = 0.6.7
+PKGNAME = ${DISTNAME:L}
HOMEPAGE = https://bsd.ac/
MAINTAINER = Aisha Tammy <open...@aisha.cc>
@@ -15,24 +15,28 @@ MAINTAINER = Aisha Tammy <open...@aisha.cc>
PERMIT_PACKAGE = Yes
# uses pledge()
-WANTLIB += ${COMPILER_LIBCXX} c m usockets
+WANTLIB += ${COMPILER_LIBCXX} c lmdb usockets
+
+# C++17
+COMPILER = base-clang ports-gcc
-# C++2a
-COMPILER = base-clang
+MODULES = devel/meson
-BUILD_DEPENDS = www/uwebsockets
+CXXFLAGS += -I${LOCALBASE}/include
-LIB_DEPENDS = net/usockets
+CONFIGURE_ENV = LDFLAGS="${LDFLAGS} -L${LOCALBASE}/lib"
-NO_TEST = Yes
+# ssl tests fail
+CONFIGURE_ARGS= -Denable_testing=true \
+ -Dtest_shuf=gshuf \
+ -Dtest_seq=gseq
-post-install:
- ${INSTALL_DATA_DIR} ${PREFIX}/share/purritobin
- ${INSTALL_DATA} ${WRKSRC}/frontend/paste.html \
- ${PREFIX}/share/purritobin
- ${INSTALL_DATA} ${WRKSRC}/clients/POSIX_shell_client.sh \
- ${PREFIX}/share/purritobin
+BUILD_DEPENDS = databases/lmdbxx \
+ net/curl \
+ sysutils/coreutils \
+ www/uwebsockets
-FAKE_FLAGS = PREFIX=${TRUEPREFIX}
+LIB_DEPENDS = databases/lmdb \
+ net/usockets
.include <bsd.port.mk>
diff --git a/www/purritobin/distinfo b/www/purritobin/distinfo
index 71fc842ca7f..ca476eddb8f 100644
--- a/www/purritobin/distinfo
+++ b/www/purritobin/distinfo
@@ -1,2 +1,2 @@
-SHA256 (PurritoBin-0.3.3.tar.gz) = lmjTCXskzvTd8eCKxlGfClbEfk6COuqh90nqHSeQ1wc=
-SIZE (PurritoBin-0.3.3.tar.gz) = 13155
+SHA256 (PurritoBin-0.6.7.tar.gz) = ulpbdPB3lCpfNJRfW/oEqd8yJ0+NNdL4wwGhRuSQWvg=
+SIZE (PurritoBin-0.6.7.tar.gz) = 20461
diff --git a/www/purritobin/pkg/PLIST b/www/purritobin/pkg/PLIST
index c09a1f0e346..e599cd370bc 100644
--- a/www/purritobin/pkg/PLIST
+++ b/www/purritobin/pkg/PLIST
@@ -4,12 +4,13 @@
@rcscript ${RCDIR}/purritobin
@bin bin/purrito
@man man/man1/purrito.1
+share/PurritoBin/
+share/PurritoBin/POSIX_shell_client.sh
+share/PurritoBin/about.html
+share/PurritoBin/index.html
+share/PurritoBin/paste.html
share/doc/pkg-readmes/${PKGSTEM}
@owner _purritobin
@group _purritobin
+@sample /var/db/purritobin/
@sample /var/www/purritobin/
-@owner
-@group
-share/purritobin/
-share/purritobin/POSIX_shell_client.sh
-share/purritobin/paste.html
diff --git a/www/purritobin/pkg/README b/www/purritobin/pkg/README
index 07087bb4492..f05963c0ce0 100644
--- a/www/purritobin/pkg/README
+++ b/www/purritobin/pkg/README
@@ -13,15 +13,18 @@ You need to set at least the following option for PurritoBin
rcctl set purritobin flags -d <domain-name>
-To look at all the possible options and descriptions
+To take a quick look at all the possible options and descriptions
purrito -h
+For an in-depth explanation
+ man purrito
+
Exposing a webserver
====================
PurritoBin saves all the pastes to a single folder.
-By default it is the folder /var/www/purritobin.
+By default it is the folder ${LOCALSTATEDIR}/www/purritobin.
So it is possible to just expose the folder via httpd(8)
sample httpd(8) configuration
@@ -30,6 +33,10 @@ http_port=80
https_port=443
ext_if=egress
+# so that non suffixed paste files are recognized as
+# plain text files
+default type text/plain
+
server "bsd.ac" {
alias "www.bsd.ac"
listen on $ext_if port $http_port
@@ -44,29 +51,97 @@ server "bsd.ac" {
server "bsd.ac" {
alias "www.bsd.ac"
- listen on egress port $https_port
+ listen on $ext_if port $https_port
+ tls {
+ certificate "/etc/ssl/bsd.ac.crt"
+ key "/etc/ssl/private/bsd.ac.key"
+ }
root "/purritobin"
directory index "index.html"
}
+sample nginx(8) configuration
+-----------------------------
+user nginx;
+worker_processes 1;
+error_log /var/log/nginx/error.log warn;
+pid /var/run/nginx.pid;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type text/plain;
+ charset utf-8;
+ log_format main '$remote_addr - $remote_user [$time_local]
"$request" '
+ '$status $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for"';
+ access_log /var/log/nginx/access.log main;
+ sendfile on;
+ keepalive_timeout 65;
+
+ server {
+ listen 80 default_server;
+ location / {
+ return 301 https://$host$request_uri;
+ }
+ location /.well-known/acme-challenge/ {
+ alias /var/www/acme-challenge/;
+ }
+ }
+
+ server {
+ listen 443 ssl;
+ server_name bsd.ac www.bsd.ac;
+
+ ssl_certificate /etc/ssl/bsd.ac.crt;
+ ssl_certificate_key /etc/ssl/private/bsd.ac.key;
+
+ # to allow online paste submission
+ add_header 'Access-Control-Allow-Origin' 'https://bsd.ac:42069';
+
+ root /var/www/purritobin;
+ location /.well-known/acme-challenge/ {
+ alias /var/www/acme-challenge/;
+ }
+ }
+}
+
+
Encrypted pastes
================
The default clients of PurritoBin are installed to
-${PREFIX}/share/purritobin/POSIX_shell_clients.sh
+${PREFIX}/share/purritobin/POSIX_shell_client.sh
To enable server side support for these pastes
make sure that paste.html file located at
${PREFIX}/share/purritobin/paste.html
is available for viewing, typically possible by just
-dumping the file into /var/www/purritobin
+dumping the file into ${LOCALSTATEDIR}/www/purritobin
+
+
+Online pasting through web-portal
+=================================
+
+To paste using the javascript form, the CORS header
+from both the paste server and the http server need to
+allow each other in the "Access-Control-Allow-Origin"
+HTTP header.
+
+An example for setting the CORS header in purrito(1)
+is available in the man page. As httpd(8) does not allow
+setting HTTP headers, relayd(8) can be used as a workaround,
+or the above nginx(8) example can be used.
PF bruteforce blocking
======================
-PurritoBin exposes a port using -p <port> (by default: 42069) for
+PurritoBin exposes ports using -p <port> (by default: 42069) for
clients to post their pastes.
PurritoBin does not enforce any rate limiting for number of pastes
at a time as this can be done much better using pf(4)
@@ -83,7 +158,7 @@ pass # establish keep-state
block quick from <bruteforce>
-# no more than one connection every 3 seconds
+# no more than 1 connection every 3 seconds
pass in on egress proto tcp from any to any port $purritobin_port \
flags S/SA keep state \
(max-src-conn-rate 1/3, \
@@ -94,20 +169,3 @@ block return in on ! lo0 proto tcp to port 6000:6010
# Port build user does not need network
block return out log proto {tcp udp} user _pbuild
-
-
-Cron job for cleaning
-=====================
-
-PurritoBin leaves the cleaning upto the webmaster.
-Fortunately, due to the simple storage mechanism, you can
-do the cleaning very easily in daily.local
-
-sample daily.local for cron cleanup
------------------------------------
-
-find /var/www/purritobin/ -type f ! -name index.html \
- ! -name paste.html \
- -delete
-
-This clears all pastes which were done during the day.
diff --git a/www/uwebsockets/Makefile b/www/uwebsockets/Makefile
index 98d36ebdb9c..df1a457e98f 100644
--- a/www/uwebsockets/Makefile
+++ b/www/uwebsockets/Makefile
@@ -1,12 +1,12 @@
# $OpenBSD: Makefile,v 1.4 2020/12/11 22:36:25 sthen Exp $
COMMENT = ultra fast, simple, secure, standards compliant web server
-PKGNAME = ${DISTNAME:L}
CATEGORIES = www
GH_ACCOUNT = uNetworking
GH_PROJECT = uWebSockets
-GH_TAGNAME = v18.17.0
+GH_TAGNAME = v20.6.0
+PKGNAME = ${DISTNAME:L}
MAINTAINER = Aisha Tammy <open...@aisha.cc>
@@ -21,9 +21,7 @@ NO_BUILD = Yes
NO_TEST = Yes
do-install:
- ${INSTALL_DATA_DIR} ${PREFIX}/include/uWebSockets/f2
+ ${INSTALL_DATA_DIR} ${PREFIX}/include/uWebSockets
${INSTALL_DATA} ${WRKSRC}/src/*.h ${PREFIX}/include/uWebSockets
- ${INSTALL_DATA} ${WRKSRC}/src/f2/*.hpp \
- ${PREFIX}/include/uWebSockets/f2
.include <bsd.port.mk>
diff --git a/www/uwebsockets/distinfo b/www/uwebsockets/distinfo
index 0d9ebdb3b51..4b1e4bc14ff 100644
--- a/www/uwebsockets/distinfo
+++ b/www/uwebsockets/distinfo
@@ -1,2 +1,2 @@
-SHA256 (uWebSockets-18.17.0.tar.gz) =
4tK9Dlm9a1RCcKo0gAP9SkI5EBW0vw61TgFhrRCPkT8=
-SIZE (uWebSockets-18.17.0.tar.gz) = 276629
+SHA256 (uWebSockets-20.6.0.tar.gz) =
It0+s1xaUEKu8Lsx9xgpXgsyOwT2PCRDpvEd3tldW9k=
+SIZE (uWebSockets-20.6.0.tar.gz) = 747993
diff --git a/www/uwebsockets/pkg/PLIST b/www/uwebsockets/pkg/PLIST
index 93802815df0..80010cdaac8 100644
--- a/www/uwebsockets/pkg/PLIST
+++ b/www/uwebsockets/pkg/PLIST
@@ -13,6 +13,7 @@ include/uWebSockets/HttpRouter.h
include/uWebSockets/Loop.h
include/uWebSockets/LoopData.h
include/uWebSockets/MessageParser.h
+include/uWebSockets/MoveOnlyFunction.h
include/uWebSockets/Multipart.h
include/uWebSockets/PerMessageDeflate.h
include/uWebSockets/ProxyParser.h
@@ -26,5 +27,3 @@ include/uWebSockets/WebSocketData.h
include/uWebSockets/WebSocketExtensions.h
include/uWebSockets/WebSocketHandshake.h
include/uWebSockets/WebSocketProtocol.h
-include/uWebSockets/f2/
-include/uWebSockets/f2/function2.hpp