Add EN-19:01 through EN-19:05.

Approved by:	so
This commit is contained in:
Gordon Tetlow 2019-01-09 19:17:54 +00:00
parent 032abc8ca4
commit 05104ff48a
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=52756
18 changed files with 143725 additions and 0 deletions

View file

@ -0,0 +1,194 @@
--- sys/netinet/cc/cc.h.orig
+++ sys/netinet/cc/cc.h
@@ -102,8 +102,6 @@
#define CCF_ACKNOW 0x0008 /* Will this ack be sent now? */
#define CCF_IPHDR_CE 0x0010 /* Does this packet set CE bit? */
#define CCF_TCPHDR_CWR 0x0020 /* Does this packet set CWR bit? */
-#define CCF_MAX_CWND 0x0040 /* Have we reached maximum cwnd? */
-#define CCF_CHG_MAX_CWND 0x0080 /* Cubic max_cwnd changed, for K */
/* ACK types passed to the ack_received() hook. */
#define CC_ACK 0x0001 /* Regular in sequence ACK. */
--- sys/netinet/cc/cc_cubic.c.orig
+++ sys/netinet/cc/cc_cubic.c
@@ -88,8 +88,6 @@
unsigned long max_cwnd;
/* cwnd at the previous congestion event. */
unsigned long prev_max_cwnd;
- /* Cached value for t_maxseg when K was computed */
- uint32_t k_maxseg;
/* Number of congestion events. */
uint32_t num_cong_events;
/* Minimum observed rtt in ticks. */
@@ -126,9 +124,6 @@
cubic_data = ccv->cc_data;
cubic_record_rtt(ccv);
- if (ccv->flags & CCF_MAX_CWND)
- return;
-
/*
* Regular ACK and we're not in cong/fast recovery and we're cwnd
* limited and we're either not doing ABC or are slow starting or are
@@ -156,12 +151,6 @@
cubic_data->mean_rtt_ticks, cubic_data->max_cwnd,
CCV(ccv, t_maxseg));
- if (ccv->flags & CCF_CHG_MAX_CWND || cubic_data->k_maxseg != CCV(ccv, t_maxseg)) {
- cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
- cubic_data->k_maxseg = CCV(ccv, t_maxseg);
- ccv->flags &= ~(CCF_MAX_CWND|CCF_CHG_MAX_CWND);
- }
-
w_cubic_next = cubic_cwnd(ticks_since_cong +
cubic_data->mean_rtt_ticks, cubic_data->max_cwnd,
CCV(ccv, t_maxseg), cubic_data->K);
@@ -173,18 +162,13 @@
* TCP-friendly region, follow tf
* cwnd growth.
*/
- CCV(ccv, snd_cwnd) = ulmin(w_tf, TCP_MAXWIN << CCV(ccv, snd_scale));
+ CCV(ccv, snd_cwnd) = w_tf;
else if (CCV(ccv, snd_cwnd) < w_cubic_next) {
/*
* Concave or convex region, follow CUBIC
* cwnd growth.
*/
- if (w_cubic_next >= TCP_MAXWIN << CCV(ccv, snd_scale)) {
- w_cubic_next = TCP_MAXWIN << CCV(ccv, snd_scale);
- ccv->flags |= CCF_MAX_CWND;
- }
- w_cubic_next = ulmin(w_cubic_next, TCP_MAXWIN << CCV(ccv, snd_scale));
if (V_tcp_do_rfc3465)
CCV(ccv, snd_cwnd) = w_cubic_next;
else
@@ -202,10 +186,8 @@
* max_cwnd.
*/
if (cubic_data->num_cong_events == 0 &&
- cubic_data->max_cwnd < CCV(ccv, snd_cwnd)) {
+ cubic_data->max_cwnd < CCV(ccv, snd_cwnd))
cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
- ccv->flags |= CCF_CHG_MAX_CWND;
- }
}
}
}
@@ -254,7 +236,6 @@
cubic_data->num_cong_events++;
cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
- ccv->flags |= CCF_CHG_MAX_CWND;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
@@ -267,8 +248,6 @@
cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
cubic_data->t_last_cong = ticks;
- ccv->flags |= CCF_CHG_MAX_CWND;
- ccv->flags &= ~CCF_MAX_CWND;
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
}
@@ -285,7 +264,6 @@
if (CCV(ccv, t_rxtshift) >= 2) {
cubic_data->num_cong_events++;
cubic_data->t_last_cong = ticks;
- ccv->flags &= ~CCF_MAX_CWND;
}
break;
}
@@ -304,7 +282,6 @@
* get used.
*/
cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
- ccv->flags |= CCF_CHG_MAX_CWND;
}
static int
@@ -329,11 +306,9 @@
pipe = 0;
/* Fast convergence heuristic. */
- if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd) {
+ if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd)
cubic_data->max_cwnd = (cubic_data->max_cwnd * CUBIC_FC_FACTOR)
>> CUBIC_SHIFT;
- ccv->flags |= CCF_CHG_MAX_CWND;
- }
if (IN_FASTRECOVERY(CCV(ccv, t_flags))) {
/*
@@ -356,7 +331,6 @@
cubic_data->max_cwnd) >> CUBIC_SHIFT));
}
cubic_data->t_last_cong = ticks;
- ccv->flags &= ~CCF_MAX_CWND;
/* Calculate the average RTT between congestion epochs. */
if (cubic_data->epoch_ack_count > 0 &&
@@ -367,6 +341,7 @@
cubic_data->epoch_ack_count = 0;
cubic_data->sum_rtt_ticks = 0;
+ cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
}
/*
--- sys/netinet/cc/cc_cubic.h.orig
+++ sys/netinet/cc/cc_cubic.h
@@ -41,8 +41,6 @@
#ifndef _NETINET_CC_CUBIC_H_
#define _NETINET_CC_CUBIC_H_
-#include <sys/limits.h>
-
/* Number of bits of precision for fixed point math calcs. */
#define CUBIC_SHIFT 8
@@ -163,6 +161,8 @@
/*
* Compute the new cwnd value using an implementation of eqn 1 from the I-D.
* Thanks to Kip Macy for help debugging this function.
+ *
+ * XXXLAS: Characterise bounds for overflow.
*/
static __inline unsigned long
cubic_cwnd(int ticks_since_cong, unsigned long wmax, uint32_t smss, int64_t K)
@@ -174,15 +174,6 @@
/* t - K, with CUBIC_SHIFT worth of precision. */
cwnd = ((int64_t)(ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz;
- /* moved this calculation up because it cannot overflow or underflow */
- cwnd *= CUBIC_C_FACTOR * smss;
-
- if (cwnd > 2097151) /* 2^21 cubed is long max */
- return INT_MAX;
-
- if (cwnd < -2097152) /* -2^21 cubed is long min */
- return smss;
-
/* (t - K)^3, with CUBIC_SHIFT^3 worth of precision. */
cwnd *= (cwnd * cwnd);
@@ -191,17 +182,8 @@
* The down shift by CUBIC_SHIFT_4 is because cwnd has 4 lots of
* CUBIC_SHIFT included in the value. 3 from the cubing of cwnd above,
* and an extra from multiplying through by CUBIC_C_FACTOR.
- *
- * The original formula was this:
- * cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax;
- *
- * CUBIC_C_FACTOR and smss factors were moved up to an earlier
- * calculation to simplify overflow and underflow detection.
*/
- cwnd = (cwnd >> CUBIC_SHIFT_4) + wmax;
-
- if (cwnd < 0)
- return 1;
+ cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax;
return ((unsigned long)cwnd);
}

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RhZfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cK6Bw/+NJXfzNxz2c9hS4RgZSeDZxtqPEC6ZG5aKN2vc7RzwYsGgv5f4VzuU40A
MsRNRmbDjoQYj9zkBKOYUWaIX6ZffOjUwc7DZ1Us4ykXRxlB2Ys4R98z5lY6mQDA
hcTnCPvKTMChcXO3hQ77W3bUPk+p5+XvcDhks8K8N5/Xixj1xoy5J8dmbGvQ9i/R
JZa2loacsPab/c2Fr/6L7DyHU3bbXIh+27HknCUOyK0dekbZ8g0oP+u/qb4VX/7s
BkSbIkLUNq3dBkb0vOAoTry/M2kKpU8Dz/SITuW4bSJqfvNWN2hiT7YTQaNg+E0J
VaaKHhpGO5TrYDnYRfmJyrAiobROEbpoGXg9TvfZ9VLk0sGOPcBN598DNJLkiZCa
dzMrimOOcgeeyPhvG0Mq4ZGBkYgqj88jb29bwJbkCLvjTfaL3kPeKxky1bylgEmR
Vevzqlp9IhrnSW21u0Kd8ZWuXka8ni+uKe2B24FyOZntziODWOi/rFAE7DV21y1V
gZsX2v9kwr/M2ApFpAhtEnF3JHX0sl5J8mF9Wnv0CdJP3fTpC9M0byZsCc2qy84g
5f6KPu57CgvuHG/YRKLDxG7tt1jXYi/LFsR7iGbbCCbthx5pImQrYfKMOdSR81s+
Iwa8j657nxF+YjM+aq8l7E3g1uonJ2aWT95WFssUnv2ww+O14fw=
=4RIV
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,56 @@
--- sys/netinet/tcp_reass.c.orig
+++ sys/netinet/tcp_reass.c
@@ -579,7 +579,8 @@
*/
lenofoh = tcp_reass_overhead_of_chain(m, &mlast);
sb = &tp->t_inpcb->inp_socket->so_rcv;
- if ((sb->sb_mbcnt + tp->t_segqmbuflen + lenofoh) > sb->sb_mbmax) {
+ if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) &&
+ (sb->sb_mbcnt + tp->t_segqmbuflen + lenofoh) > sb->sb_mbmax) {
/* No room */
TCPSTAT_INC(tcps_rcvreassfull);
#ifdef TCP_REASS_COUNTERS
@@ -588,6 +589,11 @@
#ifdef TCP_REASS_LOGGING
tcp_log_reassm(tp, NULL, NULL, th->th_seq, lenofoh, TCP_R_LOG_LIMIT_REACHED, 0);
#endif
+ if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
+ log(LOG_DEBUG, "%s; %s: mbuf count limit reached, "
+ "segment dropped\n", s, __func__);
+ free(s, M_TCPLOG);
+ }
m_freem(m);
*tlenp = 0;
#ifdef TCP_REASS_LOGGING
@@ -936,6 +942,20 @@
* is understood.
*/
new_entry:
+ if (th->th_seq == tp->rcv_nxt && TCPS_HAVEESTABLISHED(tp->t_state)) {
+ tp->rcv_nxt += *tlenp;
+ flags = th->th_flags & TH_FIN;
+ TCPSTAT_INC(tcps_rcvoopack);
+ TCPSTAT_ADD(tcps_rcvoobyte, *tlenp);
+ SOCKBUF_LOCK(&so->so_rcv);
+ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
+ m_freem(m);
+ } else {
+ sbappendstream_locked(&so->so_rcv, m, 0);
+ }
+ sorwakeup_locked(so);
+ return (flags);
+ }
if (tcp_new_limits) {
if ((tp->t_segqlen > tcp_reass_queue_guard) &&
(*tlenp < MSIZE)) {
@@ -960,9 +980,7 @@
return (0);
}
} else {
-
- if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) &&
- tp->t_segqlen >= min((so->so_rcv.sb_hiwat / tp->t_maxseg) + 1,
+ if (tp->t_segqlen >= min((so->so_rcv.sb_hiwat / tp->t_maxseg) + 1,
tcp_reass_maxqueuelen)) {
TCPSTAT_INC(tcps_rcvreassfull);
*tlenp = 0;

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RhxfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cIsjBAAiM9K9Y/ci+sVsH0HrunEbdJT5dI4oabI6Z7zV7X2F5OZobC0neXYCpqH
sknU/phwdWTmSdLlqxI37At2rQPRFnnAF0sfyByJEmnrNq3CPg/cFabvuNWfetPh
wpHQc7XUJAz58Lk5o382Dn4POZP+aBmo1e6ULHIXCcgR8xHvGAtQoCLJFh9VXKZx
tSP+PiwCfHXjIF1J+bEPhv6IO3H59COb5daj1qhTbUnkCmacPBDCFzrSqqbUPOru
MAvXxcUP3mhPDrIx5eDUNo5C1t54PF6fPzBj8Pq+SUKXrHI1PYHxw2yL+y0vn7vT
TImWde+rRdDwzab2mt/IP2WaRnC5wVNS+QHZc9M+QB+ujAx8e278uK/eiJwKkm59
MShtZ46YB96aoZuLYibk+i53jW7OOJbCH9xwFXvZb2n3ObBfJcqig4aXtvug7BOr
v/90s6Q72jKpJUopgzFut6E2XtJ6ImAvq8qDxo0qLix5vASu57tst/5vyfj4dt79
AJ05x20KKKKhaNzpnwyOWW4/egeElJPLHg8WsWzwtsRW1ZMWBRIqAzS+dLlDNod9
ywSbOYb0FMmYe0rtv1gbm5wWjAQ8QYEe/8JoD7y5O04mUVmxmubeYYQ2vAxtxDPs
ODiJtLdALWkPidb8ynn4r5LBYDjQRvni1+3j2E+nCh9Z08nHzzs=
=KVpY
-----END PGP SIGNATURE-----

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RiJfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cJUcA//Sbp6kYL6InxUHPlQYO+MSTT+vc8bnzo7pW2sGs9VP+mnseZUQLO8pp29
cCYNOC+4W2aIRP236IgeyPWSWUFSQ2MY+TSBxwa2kbIQW6Dts3ZvJNGT2MrMFqfx
4mXMf8bgrsgGHymJ7qTgudeQzgsl0OPSzXSVzp/KVT+VQb9gIok3Dx7gGzTj/u2O
5NIok6oBxUUcuoFfMV5z1fVS3Ny/gK80BVQy0f8ZlutkVZ2H09zu1pnHSLUCnUYT
psE5QlJZ/baCkPBioComDJsy8YqEf9E4W4rm/Ds/tzV+IA5s7RzH/HvfHp3j7t8l
ODNBr13lAlV6hQ71CwAPJEH5R8tmzRTKBQInAIS3xKiNBWqhshWf//ZSobHCPqJT
BDEnE/9XF1GHaa4vb5RTZRIEhTU0zJ+o1CQOR6McdJ4IxOc1P23hOvRwkylQB84S
E/3Yy42bde5RLnDYdQuxCW/c6S3PRo1jSMYjS7DnQ2PS8k+wAeAzHgj575UpcpDl
5pSuzejvobSd0qyqwmBjKVWqAhkrRcUw/Yy/wt62RyHepEtpLat6U9deq481eart
IC3eDJAaPW06mnmT9nfAqSh2CKvFUxTQ1XwZh0R+ZltdtjWFVWsU1XMc5fsfiQKU
aD3o/huTvc2MhYTexvqYQcWZYndMgnXgWQt2LqLoe0YZAgMX5ZU=
=I2kE
-----END PGP SIGNATURE-----

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RiZfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cJ1DxAAnbAtjFeY6WfYrVaBB1GHJGdIKQrgq3yzHxd3ycQYguOqjHYkagR7TLM4
Eo7/hUjTos7yvgw7A7IOVg6HqpcTuQNRHu6T5MjnHoNiB5pNgjN/OYlJ1v1nDSRR
PiNoBX1NhrUiZc8eMblZESdq2COuph9wdLJGiZeA69uTDzLTvnhIvmaFwLBM0ewl
wqK0ND3Z+bVLxuxdeRI7n616HCkQ9EgP2S8uPONZEmMaI1J00018bGOZTmBYaE9x
3/LYfR5F1ggBq5J7Vxa62z0s0vVUu8AAIE422MmqpNONgSqRQ7c2tlYi4x8NLLbs
feKuS6l181m7gN0Jc6OJZfnuEkFC1P8y3Klg9ruERX5kNKGc0cJQ5tTEzGLRxflV
eHHczHFHe6h45W9LDrkhQgOWF/ofATOIjkch0G3i5aoegBMuf0ISFZaqHm11fxnO
AAc8HY1pn6qSgMaJH33xAjCdWvGJHv8Dln08Bag9L80qW+7JoGADVTpDqJ9jqENR
2w/dQH+1AQTH3TVI7GaOYVD2f73o+YJ/SJjJQ6SrvhKaQ0MIzKRwqhsD3DgfG6ux
FYc6/5mv/yljxBPR/K7FNbd+XIz5SyicoXe7Xkk/GxChtjfKrYwK/LyWIHZfrX9N
nBNecHd8XRnpEDqdQ2qStNkWdkaX8KixcBhX18SkHDchhjJF7BY=
=M+mD
-----END PGP SIGNATURE-----

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2Ri1fFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cJtHA/+JOl78JntS1QrQn11yftlRvHgwMHbp8tOpQ9TWNsuw0uBpeIbf8ZqGRaK
BGMW+Ph77x2dMD8tt8sGYDWy1xsUUVfy7EGF7zEFjCx69hGFxno652/MrGvCYNgo
tWfbjYJhJsHaplkNFZPdIvtWfQ1IGGHKEUMnTEoCr75NeXscuUCpBtpZFnJdYry+
EHCHd2/If/49YF0PPs7zctM02KPAb52h+wwdbv19HyBD1UWuqGb3YZEPsH1btSs6
iAdEut+nrFBt5iL+fJE+CRTFXWyZoU5WD95+fmb4p4dPtisCey5QE0iSN/MCw5xB
Kj6+MuRJ+jAmWufNE+DIJYbSqosIH9zvDt0NXpgWUOlsdE87jdMGl0DgNK7eaScQ
5AqeUFFXgv63kHXl90vln/m+rIYI3xjkrAij6mkjDHAIFpE9rKVtQAezbxZ/6p7v
ZoIY4d8mb8oZhRfwd8/mAvzqTQWFnyw0OImzk7NMLj9a4idq0eTyXq1qbceuc1pt
QUJtbWfKDptN9GDNPE37FulsiLufaeNPleA54U4XRLyBYMnZfc4yPfdcy8b10GCf
zwy6bn+mZaFsOkMoLHd2pRV3erdXF8H42qUGAAW9I9Zqy2+hN87IDZ2ZUPHEYdxF
5+jD/4HsHgFgMjakP/7CJPdcVrf/pyY2PGP1Qf5dS8C4wqvbl/k=
=9pQl
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,49 @@
--- sys/kern/kern_event.c.orig
+++ sys/kern/kern_event.c
@@ -1296,6 +1296,8 @@
kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT);
kn->kn_status = KN_INFLUX|KN_DETACHED;
+ if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
error = knote_attach(kn, kq);
KQ_UNLOCK(kq);
@@ -1332,6 +1334,11 @@
KNOTE_ACTIVATE(kn, 1);
}
+ if ((kev->flags & EV_ENABLE) != 0)
+ kn->kn_status &= ~KN_DISABLED;
+ else if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
+
/*
* The user may change some filter values after the initial EV_ADD,
* but doing so will not reset any filter which has already been
@@ -1348,19 +1355,17 @@
kn->kn_sdata = kev->data;
}
+done_ev_add:
/*
* We can get here with kn->kn_knlist == NULL. This can happen when
* the initial attach event decides that the event is "completed"
- * already. i.e. filt_procattach is called on a zombie process. It
- * will call filt_proc which will remove it from the list, and NULL
+ * already, e.g., filt_procattach() is called on a zombie process. It
+ * will call filt_proc() which will remove it from the list, and NULL
* kn_knlist.
+ *
+ * KN_DISABLED will be stable while the knote is in flux, so the
+ * unlocked read will not race with an update.
*/
-done_ev_add:
- if ((kev->flags & EV_ENABLE) != 0)
- kn->kn_status &= ~KN_DISABLED;
- else if ((kev->flags & EV_DISABLE) != 0)
- kn->kn_status |= KN_DISABLED;
-
if ((kn->kn_status & KN_DISABLED) == 0)
event = kn->kn_fop->f_event(kn, 0);
else

View file

@ -0,0 +1,18 @@
-----BEGIN PGP SIGNATURE-----
iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RjRfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
5cLrQRAAlMBtUSxbiSdLI8KfeKYj2Xe2cAvVfK+oK+pooErNX6TyofIyewrck4PB
xZ/c7clZg3WRKAZJ1D6RacF02coBlCJHJbajMtjrIO6p3lXLX7FalxrIc9APiDI1
n5he7Ij5Uu6FedPqJmSu81wOfInI+mX6vhap2UFrajFXI1iexhT4FiANtHGxTQwG
I8GlFfptT7QY1dUugt2+KRoYFobUv4SQynhgDb1CfMZ55SCjnkEPIqE6dMsv/f4d
iKBQoMmI8oBB6LLP1YhsidgG7LS84A+CwGXf9KQHRrugU9pPy2b8nQodGBzfmv4c
UaVJYO7hIkCof+4loloJrxEATWNnb2V5XlJumY6ENQwCCjttD/TOnfAAbUCkajZW
t+LZu5MkTZpx/Zyby9ojHl6yd7u7Cc2klN56vyOjGGBZ9PbXjsrwllEonnlHEThY
NDwcML8kjXPCXwgHtysKTxJKT9HsaG5tL/PMdTeHUwmkAfYyOeOTL14wpoF5//tc
akIcGw5qQjfFFaFCkfdFwktF63Hdsv8/G56sDBYHsdPE7Bwj4cnJhasWWtUTTN5t
XOvxoGUMOKwyQ/tUlNHvuyOEieEy781LYqHhVQObI00qkeSOJmwKaDuOjNd64wjv
2jJ4ZLegckyQlYR4GKGr6L0h6WTyL+d4xXZ7EcOxdkDa/dAYnHQ=
=Er0a
-----END PGP SIGNATURE-----