xref: /dragonfly/sys/netgraph7/deflate/ng_deflate.c (revision 05d02a3813e2bef176c69d68035311fd2efbd031)
1 /*-
2  * Copyright (c) 2006 Alexander Motin <mav@alkar.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD: src/sys/netgraph/ng_deflate.c,v 1.3 2007/01/15 05:55:56 glebius Exp $
28  */
29 
30 /*
31  * Deflate PPP compression netgraph node type.
32  */
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/mbuf.h>
38 #include <sys/malloc.h>
39 #include <sys/errno.h>
40 #include <sys/syslog.h>
41 
42 #include <net/zlib.h>
43 
44 #include <netgraph7/ng_message.h>
45 #include <netgraph7/netgraph.h>
46 #include <netgraph7/ng_parse.h>
47 #include "ng_deflate.h"
48 
49 #include "opt_netgraph.h"
50 
51 MALLOC_DEFINE(M_NETGRAPH_DEFLATE, "netgraph_deflate", "netgraph deflate node ");
52 
53 /* DEFLATE header length */
54 #define DEFLATE_HDRLEN                  2
55 
56 #define PROT_COMPD            0x00fd
57 
58 #define DEFLATE_BUF_SIZE      4096
59 
60 /* Node private data */
61 struct ng_deflate_private {
62           struct ng_deflate_config cfg;           /* configuration */
63           u_char              inbuf[DEFLATE_BUF_SIZE];      /* input buffer */
64           u_char              outbuf[DEFLATE_BUF_SIZE];     /* output buffer */
65           z_stream  cx;                           /* compression context */
66           struct ng_deflate_stats stats;                    /* statistics */
67           ng_ID_t             ctrlnode;           /* path to controlling node */
68           uint16_t  seqnum;                       /* sequence number */
69           u_char              compress;           /* compress/decompress flag */
70 };
71 typedef struct ng_deflate_private *priv_p;
72 
73 /* Netgraph node methods */
74 static ng_constructor_t       ng_deflate_constructor;
75 static ng_rcvmsg_t  ng_deflate_rcvmsg;
76 static ng_shutdown_t          ng_deflate_shutdown;
77 static ng_newhook_t ng_deflate_newhook;
78 static ng_rcvdata_t ng_deflate_rcvdata;
79 static ng_disconnect_t        ng_deflate_disconnect;
80 
81 /* Helper functions */
82 static void         *z_alloc(void *, u_int items, u_int size);
83 static void         z_free(void *, void *ptr);
84 static int          ng_deflate_compress(node_p node,
85                         struct mbuf *m, struct mbuf **resultp);
86 static int          ng_deflate_decompress(node_p node,
87                         struct mbuf *m, struct mbuf **resultp);
88 static void         ng_deflate_reset_req(node_p node);
89 
90 /* Parse type for struct ng_deflate_config. */
91 static const struct ng_parse_struct_field ng_deflate_config_type_fields[]
92           = NG_DEFLATE_CONFIG_INFO;
93 static const struct ng_parse_type ng_deflate_config_type = {
94           &ng_parse_struct_type,
95           ng_deflate_config_type_fields
96 };
97 
98 /* Parse type for struct ng_deflate_stat. */
99 static const struct ng_parse_struct_field ng_deflate_stats_type_fields[]
100           = NG_DEFLATE_STATS_INFO;
101 static const struct ng_parse_type ng_deflate_stat_type = {
102           &ng_parse_struct_type,
103           ng_deflate_stats_type_fields
104 };
105 
106 /* List of commands and how to convert arguments to/from ASCII. */
107 static const struct ng_cmdlist ng_deflate_cmds[] = {
108           {
109             NGM_DEFLATE_COOKIE,
110             NGM_DEFLATE_CONFIG,
111             "config",
112             &ng_deflate_config_type,
113             NULL
114           },
115           {
116             NGM_DEFLATE_COOKIE,
117             NGM_DEFLATE_RESETREQ,
118             "resetreq",
119             NULL,
120             NULL
121           },
122           {
123             NGM_DEFLATE_COOKIE,
124             NGM_DEFLATE_GET_STATS,
125             "getstats",
126             NULL,
127             &ng_deflate_stat_type
128           },
129           {
130             NGM_DEFLATE_COOKIE,
131             NGM_DEFLATE_CLR_STATS,
132             "clrstats",
133             NULL,
134             NULL
135           },
136           {
137             NGM_DEFLATE_COOKIE,
138             NGM_DEFLATE_GETCLR_STATS,
139             "getclrstats",
140             NULL,
141             &ng_deflate_stat_type
142           },
143           { 0 }
144 };
145 
146 /* Node type descriptor */
147 static struct ng_type ng_deflate_typestruct = {
148           .version =          NG_ABI_VERSION,
149           .name =             NG_DEFLATE_NODE_TYPE,
150           .constructor =      ng_deflate_constructor,
151           .rcvmsg = ng_deflate_rcvmsg,
152           .shutdown =         ng_deflate_shutdown,
153           .newhook =          ng_deflate_newhook,
154           .rcvdata =          ng_deflate_rcvdata,
155           .disconnect =       ng_deflate_disconnect,
156           .cmdlist =          ng_deflate_cmds,
157 };
158 NETGRAPH_INIT(deflate, &ng_deflate_typestruct);
159 
160 /* Depend on separate zlib module. */
161 MODULE_DEPEND(ng_deflate, zlib, 1, 1, 1);
162 
163 #define ERROUT(x)   do { error = (x); goto done; } while (0)
164 
165 /************************************************************************
166                               NETGRAPH NODE STUFF
167  ************************************************************************/
168 
169 /*
170  * Node type constructor
171  */
172 static int
ng_deflate_constructor(node_p node)173 ng_deflate_constructor(node_p node)
174 {
175           priv_p priv;
176 
177           /* Allocate private structure. */
178           priv = kmalloc(sizeof(*priv), M_NETGRAPH_DEFLATE, M_WAITOK | M_ZERO);
179 
180           NG_NODE_SET_PRIVATE(node, priv);
181 
182           /* This node is not thread safe. */
183           NG_NODE_FORCE_WRITER(node);
184 
185           /* Done */
186           return (0);
187 }
188 
189 /*
190  * Give our OK for a hook to be added.
191  */
192 static int
ng_deflate_newhook(node_p node,hook_p hook,const char * name)193 ng_deflate_newhook(node_p node, hook_p hook, const char *name)
194 {
195           const priv_p priv = NG_NODE_PRIVATE(node);
196 
197           if (NG_NODE_NUMHOOKS(node) > 0)
198                     return (EINVAL);
199 
200           if (strcmp(name, NG_DEFLATE_HOOK_COMP) == 0)
201                     priv->compress = 1;
202           else if (strcmp(name, NG_DEFLATE_HOOK_DECOMP) == 0)
203                     priv->compress = 0;
204           else
205                     return (EINVAL);
206 
207           return (0);
208 }
209 
210 /*
211  * Receive a control message
212  */
213 static int
ng_deflate_rcvmsg(node_p node,item_p item,hook_p lasthook)214 ng_deflate_rcvmsg(node_p node, item_p item, hook_p lasthook)
215 {
216           const priv_p priv = NG_NODE_PRIVATE(node);
217           struct ng_mesg *resp = NULL;
218           int error = 0;
219           struct ng_mesg *msg;
220 
221           NGI_GET_MSG(item, msg);
222 
223           if (msg->header.typecookie != NGM_DEFLATE_COOKIE)
224                     ERROUT(EINVAL);
225 
226           switch (msg->header.cmd) {
227           case NGM_DEFLATE_CONFIG:
228               {
229                     struct ng_deflate_config *const cfg
230                         = (struct ng_deflate_config *)msg->data;
231 
232                     /* Check configuration. */
233                     if (msg->header.arglen != sizeof(*cfg))
234                               ERROUT(EINVAL);
235                     if (cfg->enable) {
236                         if (cfg->windowBits < 8 || cfg->windowBits > 15)
237                               ERROUT(EINVAL);
238                     } else
239                         cfg->windowBits = 0;
240 
241                     /* Clear previous state. */
242                     if (priv->cfg.enable) {
243                               if (priv->compress)
244                                         deflateEnd(&priv->cx);
245                               else
246                                         inflateEnd(&priv->cx);
247                               priv->cfg.enable = 0;
248                     }
249 
250                     /* Configuration is OK, reset to it. */
251                     priv->cfg = *cfg;
252 
253                     if (priv->cfg.enable) {
254                               priv->cx.next_in = NULL;
255                               priv->cx.zalloc = z_alloc;
256                               priv->cx.zfree = z_free;
257                               int res;
258                               if (priv->compress) {
259                                         if ((res = deflateInit2(&priv->cx,
260                                             Z_DEFAULT_COMPRESSION, Z_DEFLATED,
261                                             -cfg->windowBits, 8,
262                                             Z_DEFAULT_STRATEGY)) != Z_OK) {
263                                                   log(LOG_NOTICE,
264                                                       "deflateInit2: error %d, %s\n",
265                                                       res, priv->cx.msg);
266                                                   priv->cfg.enable = 0;
267                                                   ERROUT(ENOMEM);
268                                         }
269                               } else {
270                                         if ((res = inflateInit2(&priv->cx,
271                                             -cfg->windowBits)) != Z_OK) {
272                                                   log(LOG_NOTICE,
273                                                       "inflateInit2: error %d, %s\n",
274                                                       res, priv->cx.msg);
275                                                   priv->cfg.enable = 0;
276                                                   ERROUT(ENOMEM);
277                                         }
278                               }
279                     }
280 
281                     /* Initialize other state. */
282                     priv->seqnum = 0;
283 
284                     /* Save return address so we can send reset-req's */
285                     priv->ctrlnode = NGI_RETADDR(item);
286                     break;
287               }
288 
289           case NGM_DEFLATE_RESETREQ:
290                     ng_deflate_reset_req(node);
291                     break;
292 
293           case NGM_DEFLATE_GET_STATS:
294           case NGM_DEFLATE_CLR_STATS:
295           case NGM_DEFLATE_GETCLR_STATS:
296                     /* Create response if requested. */
297                     if (msg->header.cmd != NGM_DEFLATE_CLR_STATS) {
298                               NG_MKRESPONSE(resp, msg,
299                                   sizeof(struct ng_deflate_stats), M_WAITOK | M_NULLOK);
300                               if (resp == NULL)
301                                         ERROUT(ENOMEM);
302                               bcopy(&priv->stats, resp->data,
303                                   sizeof(struct ng_deflate_stats));
304                     }
305 
306                     /* Clear stats if requested. */
307                     if (msg->header.cmd != NGM_DEFLATE_GET_STATS)
308                               bzero(&priv->stats,
309                                   sizeof(struct ng_deflate_stats));
310                     break;
311 
312           default:
313                     error = EINVAL;
314                     break;
315           }
316 done:
317           NG_RESPOND_MSG(error, node, item, resp);
318           NG_FREE_MSG(msg);
319           return (error);
320 }
321 
322 /*
323  * Receive incoming data on our hook.
324  */
325 static int
ng_deflate_rcvdata(hook_p hook,item_p item)326 ng_deflate_rcvdata(hook_p hook, item_p item)
327 {
328           const node_p node = NG_HOOK_NODE(hook);
329           const priv_p priv = NG_NODE_PRIVATE(node);
330           struct mbuf *m, *out;
331           int error;
332 
333           if (!priv->cfg.enable) {
334                     NG_FREE_ITEM(item);
335                     return (ENXIO);
336           }
337 
338           NGI_GET_M(item, m);
339           /* Compress */
340           if (priv->compress) {
341                     if ((error = ng_deflate_compress(node, m, &out)) != 0) {
342                               NG_FREE_ITEM(item);
343                               log(LOG_NOTICE, "%s: error: %d\n", __func__, error);
344                               return (error);
345                     }
346 
347           } else { /* Decompress */
348                     if ((error = ng_deflate_decompress(node, m, &out)) != 0) {
349                               NG_FREE_ITEM(item);
350                               log(LOG_NOTICE, "%s: error: %d\n", __func__, error);
351                               if (priv->ctrlnode != 0) {
352                                         struct ng_mesg *msg;
353 
354                                         /* Need to send a reset-request. */
355                                         NG_MKMESSAGE(msg, NGM_DEFLATE_COOKIE,
356                                             NGM_DEFLATE_RESETREQ, 0, M_WAITOK | M_NULLOK);
357                                         if (msg == NULL)
358                                                   return (error);
359                                         NG_SEND_MSG_ID(error, node, msg,
360                                                   priv->ctrlnode, 0);
361                               }
362                               return (error);
363                     }
364           }
365 
366           NG_FWD_NEW_DATA(error, item, hook, out);
367           return (error);
368 }
369 
370 /*
371  * Destroy node.
372  */
373 static int
ng_deflate_shutdown(node_p node)374 ng_deflate_shutdown(node_p node)
375 {
376           const priv_p priv = NG_NODE_PRIVATE(node);
377 
378           /* Take down netgraph node. */
379           if (priv->cfg.enable) {
380               if (priv->compress)
381                     deflateEnd(&priv->cx);
382               else
383                     inflateEnd(&priv->cx);
384           }
385 
386           kfree(priv, M_NETGRAPH_DEFLATE);
387           NG_NODE_SET_PRIVATE(node, NULL);
388           NG_NODE_UNREF(node);                    /* let the node escape */
389           return (0);
390 }
391 
392 /*
393  * Hook disconnection
394  */
395 static int
ng_deflate_disconnect(hook_p hook)396 ng_deflate_disconnect(hook_p hook)
397 {
398           const node_p node = NG_HOOK_NODE(hook);
399           const priv_p priv = NG_NODE_PRIVATE(node);
400 
401           if (priv->cfg.enable) {
402               if (priv->compress)
403                     deflateEnd(&priv->cx);
404               else
405                     inflateEnd(&priv->cx);
406               priv->cfg.enable = 0;
407           }
408 
409           /* Go away if no longer connected. */
410           if ((NG_NODE_NUMHOOKS(node) == 0) && NG_NODE_IS_VALID(node))
411                     ng_rmnode_self(node);
412           return (0);
413 }
414 
415 /************************************************************************
416                               HELPER STUFF
417  ************************************************************************/
418 
419 /*
420  * Space allocation and freeing routines for use by zlib routines.
421  */
422 
423 static void *
z_alloc(void * notused,u_int items,u_int size)424 z_alloc(void *notused, u_int items, u_int size)
425 {
426 
427           return (kmalloc(items * size, M_NETGRAPH_DEFLATE, M_WAITOK | M_NULLOK));
428 }
429 
430 static void
z_free(void * notused,void * ptr)431 z_free(void *notused, void *ptr)
432 {
433 
434           kfree(ptr, M_NETGRAPH_DEFLATE);
435 }
436 
437 /*
438  * Compress/encrypt a packet and put the result in a new mbuf at *resultp.
439  * The original mbuf is not free'd.
440  */
441 static int
ng_deflate_compress(node_p node,struct mbuf * m,struct mbuf ** resultp)442 ng_deflate_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
443 {
444           const priv_p        priv = NG_NODE_PRIVATE(node);
445           int                 outlen, inlen;
446           int                 rtn;
447 
448           /* Initialize. */
449           *resultp = NULL;
450 
451           inlen = m->m_pkthdr.len;
452 
453           priv->stats.FramesPlain++;
454           priv->stats.InOctets+=inlen;
455 
456           if (inlen > DEFLATE_BUF_SIZE) {
457                     priv->stats.Errors++;
458                     NG_FREE_M(m);
459                     return (ENOMEM);
460           }
461 
462           /* Work with contiguous regions of memory. */
463           m_copydata(m, 0, inlen, priv->inbuf);
464           outlen = DEFLATE_BUF_SIZE;
465 
466           /* Compress "inbuf" into "outbuf". */
467           /* Prepare to compress. */
468           if (priv->inbuf[0] != 0) {
469                     priv->cx.next_in = priv->inbuf;
470                     priv->cx.avail_in = inlen;
471           } else {
472                     priv->cx.next_in = priv->inbuf + 1; /* compress protocol */
473                     priv->cx.avail_in = inlen - 1;
474           }
475           priv->cx.next_out = priv->outbuf + 2 + DEFLATE_HDRLEN;
476           priv->cx.avail_out = outlen - 2 - DEFLATE_HDRLEN;
477 
478           /* Compress. */
479           rtn = deflate(&priv->cx, Z_PACKET_FLUSH);
480 
481           /* Check return value. */
482           if (rtn != Z_OK) {
483                     priv->stats.Errors++;
484                     log(LOG_NOTICE, "ng_deflate: compression error: %d (%s)\n",
485                         rtn, priv->cx.msg);
486                     NG_FREE_M(m);
487                     return (EINVAL);
488           }
489 
490           /* Calculate resulting size. */
491           outlen -= priv->cx.avail_out;
492 
493           /* If we can't compress this packet, send it as-is. */
494           if (outlen > inlen) {
495                     /* Return original packet uncompressed. */
496                     *resultp = m;
497                     priv->stats.FramesUncomp++;
498                     priv->stats.OutOctets+=inlen;
499           } else {
500                     NG_FREE_M(m);
501 
502                     /* Install header. */
503                     ((u_int16_t *)priv->outbuf)[0] = htons(PROT_COMPD);
504                     ((u_int16_t *)priv->outbuf)[1] = htons(priv->seqnum);
505 
506                     /* Return packet in an mbuf. */
507                     *resultp = m_devget(priv->outbuf, outlen, 0, NULL);
508                     if (*resultp == NULL) {
509                               priv->stats.Errors++;
510                               return (ENOMEM);
511                     }
512                     priv->stats.FramesComp++;
513                     priv->stats.OutOctets+=outlen;
514           }
515 
516           /* Update sequence number. */
517           priv->seqnum++;
518 
519           return (0);
520 }
521 
522 /*
523  * Decompress/decrypt packet and put the result in a new mbuf at *resultp.
524  * The original mbuf is not free'd.
525  */
526 static int
ng_deflate_decompress(node_p node,struct mbuf * m,struct mbuf ** resultp)527 ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
528 {
529           const priv_p        priv = NG_NODE_PRIVATE(node);
530           int                 outlen, inlen;
531           int                 rtn;
532           uint16_t  proto;
533           int                 offset;
534           uint16_t  rseqnum;
535 
536           /* Initialize. */
537           *resultp = NULL;
538 
539           inlen = m->m_pkthdr.len;
540 
541           if (inlen > DEFLATE_BUF_SIZE) {
542                     priv->stats.Errors++;
543                     NG_FREE_M(m);
544                     priv->seqnum = 0;
545                     return (ENOMEM);
546           }
547 
548           /* Work with contiguous regions of memory. */
549           m_copydata(m, 0, inlen, priv->inbuf);
550 
551           /* Separate proto. */
552           if ((priv->inbuf[0] & 0x01) != 0) {
553                     proto = priv->inbuf[0];
554                     offset = 1;
555           } else {
556                     proto = ntohs(((uint16_t *)priv->inbuf)[0]);
557                     offset = 2;
558           }
559 
560           priv->stats.InOctets += inlen;
561 
562           /* Packet is compressed, so decompress. */
563           if (proto == PROT_COMPD) {
564                     priv->stats.FramesComp++;
565 
566                     /* Check sequence number. */
567                     rseqnum = ntohs(((uint16_t *)(priv->inbuf + offset))[0]);
568                     offset += 2;
569                     if (rseqnum != priv->seqnum) {
570                               priv->stats.Errors++;
571                               log(LOG_NOTICE, "ng_deflate: wrong sequence: %u "
572                                   "instead of %u\n", rseqnum, priv->seqnum);
573                               NG_FREE_M(m);
574                               priv->seqnum = 0;
575                               return (EPIPE);
576                     }
577 
578                     outlen = DEFLATE_BUF_SIZE;
579 
580                     /* Decompress "inbuf" into "outbuf". */
581                     /* Prepare to decompress. */
582                     priv->cx.next_in = priv->inbuf + offset;
583                     priv->cx.avail_in = inlen - offset;
584                     /* Reserve space for protocol decompression. */
585                     priv->cx.next_out = priv->outbuf + 1;
586                     priv->cx.avail_out = outlen - 1;
587 
588                     /* Decompress. */
589                     rtn = inflate(&priv->cx, Z_PACKET_FLUSH);
590 
591                     /* Check return value. */
592                     if (rtn != Z_OK && rtn != Z_STREAM_END) {
593                               priv->stats.Errors++;
594                               NG_FREE_M(m);
595                               priv->seqnum = 0;
596                               log(LOG_NOTICE, "%s: decompression error: %d (%s)\n",
597                                   __func__, rtn, priv->cx.msg);
598 
599                               switch (rtn) {
600                               case Z_MEM_ERROR:
601                                         return (ENOMEM);
602                               case Z_DATA_ERROR:
603                                         return (EIO);
604                               default:
605                                         return (EINVAL);
606                               }
607                     }
608 
609                     /* Calculate resulting size. */
610                     outlen -= priv->cx.avail_out;
611 
612                     NG_FREE_M(m);
613 
614                     /* Decompress protocol. */
615                     if ((priv->outbuf[1] & 0x01) != 0) {
616                               priv->outbuf[0] = 0;
617                               /* Return packet in an mbuf. */
618                               *resultp = m_devget(priv->outbuf, outlen, 0, NULL);
619                     } else {
620                               outlen--;
621                               /* Return packet in an mbuf. */
622                               *resultp = m_devget(priv->outbuf + 1, outlen, 0, NULL);
623                     }
624                     if (*resultp == NULL) {
625                               priv->stats.Errors++;
626                               priv->seqnum = 0;
627                               return (ENOMEM);
628                     }
629                     priv->stats.FramesPlain++;
630                     priv->stats.OutOctets+=outlen;
631 
632           } else { /* Packet is not compressed, just update dictionary. */
633                     priv->stats.FramesUncomp++;
634                     if (priv->inbuf[0] == 0) {
635                         priv->cx.next_in = priv->inbuf + 1; /* compress protocol */
636                         priv->cx.avail_in = inlen - 1;
637                     } else {
638                         priv->cx.next_in = priv->inbuf;
639                         priv->cx.avail_in = inlen;
640                     }
641 
642                     rtn = inflateIncomp(&priv->cx);
643 
644                     /* Check return value */
645                     if (rtn != Z_OK) {
646                               priv->stats.Errors++;
647                               log(LOG_NOTICE, "%s: inflateIncomp error: %d (%s)\n",
648                                   __func__, rtn, priv->cx.msg);
649                               NG_FREE_M(m);
650                               priv->seqnum = 0;
651                               return (EINVAL);
652                     }
653 
654                     *resultp = m;
655                     priv->stats.FramesPlain++;
656                     priv->stats.OutOctets += inlen;
657           }
658 
659           /* Update sequence number. */
660           priv->seqnum++;
661 
662           return (0);
663 }
664 
665 /*
666  * The peer has sent us a CCP ResetRequest, so reset our transmit state.
667  */
668 static void
ng_deflate_reset_req(node_p node)669 ng_deflate_reset_req(node_p node)
670 {
671           const priv_p priv = NG_NODE_PRIVATE(node);
672 
673           priv->seqnum = 0;
674           if (priv->cfg.enable) {
675               if (priv->compress)
676                     deflateReset(&priv->cx);
677               else
678                     inflateReset(&priv->cx);
679           }
680 }
681 
682