Annotation of embedaddon/mpd/src/ccp_deflate.c, revision 1.1.1.2
1.1 misho 1:
2: /*
3: * ccp_deflate.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "defs.h"
9:
10: #ifdef CCP_DEFLATE
11:
12: #include "ppp.h"
13: #include "ccp.h"
14: #include "util.h"
15: #include "ngfunc.h"
16:
17: #include <netgraph/ng_message.h>
18: #include <netgraph.h>
19:
20: /*
21: * INTERNAL FUNCTIONS
22: */
23:
24: static int DeflateInit(Bund b, int direction);
25: static int DeflateConfigure(Bund b);
26: static char *DeflateDescribe(Bund b, int xmit, char *buf, size_t len);
27: static void DeflateCleanup(Bund b, int direction);
28:
29: static u_char *DeflateBuildConfigReq(Bund b, u_char *cp, int *ok);
30: static void DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode);
31: static Mbuf DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck);
32: static Mbuf DeflateSendResetReq(Bund b);
33: static void DeflateRecvResetAck(Bund b, int id, Mbuf bp);
34: static int DeflateNegotiated(Bund b, int xmit);
35: static int DeflateSubtractBloat(Bund b, int size);
36: static int DeflateStat(Context ctx, int dir);
37:
38: /*
39: * GLOBAL VARIABLES
40: */
41:
42: const struct comptype gCompDeflateInfo =
43: {
44: "deflate",
45: CCP_TY_DEFLATE,
46: 2,
47: DeflateInit,
48: DeflateConfigure,
49: NULL,
50: DeflateDescribe,
51: DeflateSubtractBloat,
52: DeflateCleanup,
53: DeflateBuildConfigReq,
54: DeflateDecodeConfigReq,
55: DeflateSendResetReq,
56: DeflateRecvResetReq,
57: DeflateRecvResetAck,
58: DeflateNegotiated,
59: DeflateStat,
60: NULL,
61: NULL,
62: };
63:
64: /*
65: * DeflateInit()
66: */
67:
68: static int
69: DeflateInit(Bund b, int dir)
70: {
71: DeflateInfo const deflate = &b->ccp.deflate;
72: struct ng_deflate_config conf;
73: struct ngm_mkpeer mp;
74: char path[NG_PATHSIZ];
75: const char *deflatehook, *ppphook;
76: ng_ID_t id;
77:
78: /* Initialize configuration structure */
79: memset(&conf, 0, sizeof(conf));
80: conf.enable = 1;
81: if (dir == COMP_DIR_XMIT) {
82: ppphook = NG_PPP_HOOK_COMPRESS;
83: deflatehook = NG_DEFLATE_HOOK_COMP;
84: conf.windowBits = deflate->xmit_windowBits;
85: } else {
86: ppphook = NG_PPP_HOOK_DECOMPRESS;
87: deflatehook = NG_DEFLATE_HOOK_DECOMP;
88: conf.windowBits = deflate->recv_windowBits;
89: }
90:
91: /* Attach a new DEFLATE node to the PPP node */
92: snprintf(path, sizeof(path), "[%x]:", b->nodeID);
93: strcpy(mp.type, NG_DEFLATE_NODE_TYPE);
94: strcpy(mp.ourhook, ppphook);
95: strcpy(mp.peerhook, deflatehook);
96: if (NgSendMsg(gCcpCsock, path,
97: NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
98: Perror("[%s] can't create %s node", b->name, mp.type);
99: return(-1);
100: }
101:
102: strlcat(path, ppphook, sizeof(path));
103:
1.1.1.2 ! misho 104: if ((id = NgGetNodeID(-1, path)) == 0) {
! 105: Perror("[%s] Cannot get %s node id", b->name, NG_DEFLATE_NODE_TYPE);
! 106: goto fail;
! 107: }
! 108:
1.1 misho 109: if (dir == COMP_DIR_XMIT) {
110: b->ccp.comp_node_id = id;
111: } else {
112: b->ccp.decomp_node_id = id;
113: }
114:
115: /* Configure DEFLATE node */
116: snprintf(path, sizeof(path), "[%x]:", id);
117: if (NgSendMsg(gCcpCsock, path,
118: NGM_DEFLATE_COOKIE, NGM_DEFLATE_CONFIG, &conf, sizeof(conf)) < 0) {
119: Perror("[%s] can't config %s node at %s",
120: b->name, NG_DEFLATE_NODE_TYPE, path);
1.1.1.2 ! misho 121: goto fail;
1.1 misho 122: }
123:
124: return 0;
1.1.1.2 ! misho 125:
! 126: fail:
! 127: NgFuncShutdownNode(gCcpCsock, b->name, path);
! 128: return(-1);
1.1 misho 129: }
130:
131: /*
132: * DeflateConfigure()
133: */
134:
135: static int
136: DeflateConfigure(Bund b)
137: {
138: CcpState const ccp = &b->ccp;
139: DeflateInfo const deflate = &ccp->deflate;
140:
141: deflate->xmit_windowBits=15;
142: deflate->recv_windowBits=0;
143:
144: return(0);
145: }
146:
147: /*
148: * DeflateCleanup()
149: */
150:
151: static char *
152: DeflateDescribe(Bund b, int dir, char *buf, size_t len)
153: {
154: CcpState const ccp = &b->ccp;
155: DeflateInfo const deflate = &ccp->deflate;
156:
157: switch (dir) {
158: case COMP_DIR_XMIT:
159: snprintf(buf, len, "win %d", deflate->xmit_windowBits);
160: break;
161: case COMP_DIR_RECV:
162: snprintf(buf, len, "win %d", deflate->recv_windowBits);
163: break;
164: default:
165: assert(0);
166: return(NULL);
167: }
168: return (buf);
169: }
170:
171: /*
172: * DeflateCleanup()
173: */
174:
175: void
176: DeflateCleanup(Bund b, int dir)
177: {
178: char path[NG_PATHSIZ];
179:
180: /* Remove node */
181: if (dir == COMP_DIR_XMIT) {
182: snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
183: b->ccp.comp_node_id = 0;
184: } else {
185: snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
186: b->ccp.decomp_node_id = 0;
187: }
188: NgFuncShutdownNode(gCcpCsock, b->name, path);
189: }
190:
191: /*
192: * DeflateRecvResetReq()
193: */
194:
195: static Mbuf
196: DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
197: {
198: char path[NG_PATHSIZ];
1.1.1.2 ! misho 199:
! 200: (void)bp;
! 201: (void)id;
! 202: (void)noAck;
! 203:
1.1 misho 204: /* Forward ResetReq to the DEFLATE compression node */
205: snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
206: if (NgSendMsg(gCcpCsock, path,
207: NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
208: Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
209: }
210: return(NULL);
211: }
212:
213: /*
214: * DeflateSendResetReq()
215: */
216:
217: static Mbuf
218: DeflateSendResetReq(Bund b)
219: {
1.1.1.2 ! misho 220: (void)b;
1.1 misho 221: return(NULL);
222: }
223:
224: /*
225: * DeflateRecvResetAck()
226: */
227:
228: static void
229: DeflateRecvResetAck(Bund b, int id, Mbuf bp)
230: {
231: char path[NG_PATHSIZ];
1.1.1.2 ! misho 232:
! 233: (void)bp;
! 234: (void)id;
! 235:
1.1 misho 236: /* Forward ResetReq to the DEFLATE compression node */
237: snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
238: if (NgSendMsg(gCcpCsock, path,
239: NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
240: Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
241: }
242: }
243:
244: /*
245: * DeflateBuildConfigReq()
246: */
247:
248: static u_char *
249: DeflateBuildConfigReq(Bund b, u_char *cp, int *ok)
250: {
251: CcpState const ccp = &b->ccp;
252: DeflateInfo const deflate = &ccp->deflate;
253: u_int16_t opt;
254:
255: if (deflate->xmit_windowBits > 0) {
256: opt = ((deflate->xmit_windowBits-8)<<12) + (8<<8) + (0<<2) + 0;
257:
258: cp = FsmConfValue(cp, CCP_TY_DEFLATE, -2, &opt);
259: *ok = 1;
260: }
261: return (cp);
262: }
263:
264: /*
265: * DeflateDecodeConfigReq()
266: */
267:
268: static void
269: DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
270: {
271: Bund b = (Bund)fp->arg;
272: CcpState const ccp = &b->ccp;
273: DeflateInfo const deflate = &ccp->deflate;
274: u_int16_t o;
275: u_char window, method, chk;
276:
277: /* Sanity check */
278: if (opt->len != 4) {
279: Log(LG_CCP, ("[%s] bogus length %d", b->name, opt->len));
280: if (mode == MODE_REQ)
281: FsmRej(fp, opt);
282: return;
283: }
284:
285: /* Get bits */
286: memcpy(&o, opt->data, 2);
287: o = ntohs(o);
288: window = (o>>12)&0x000F;
289: method = (o>>8)&0x000F;
290: chk = o&0x0003;
291:
292: /* Display it */
293: Log(LG_CCP, ("[%s] 0x%04x: w:%d, m:%d, c:%d", b->name, o, window, method, chk));
294:
295: /* Deal with it */
296: switch (mode) {
297: case MODE_REQ:
298: if ((window > 0) && (window<=7) && (method == 8) && (chk == 0)) {
299: deflate->recv_windowBits = window + 8;
300: FsmAck(fp, opt);
301: } else {
302: o = htons((7<<12) + (8<<8) + (0<<2) + 0);
303: memcpy(opt->data, &o, 2);
304: FsmNak(fp, opt);
305: }
306: break;
307:
308: case MODE_NAK:
309: if ((window > 0) && (window<=7) && (method == 8) && (chk == 0))
310: deflate->xmit_windowBits = window + 8;
311: else {
312: deflate->xmit_windowBits = 0;
313: }
314: break;
315: }
316: }
317:
318: /*
319: * DeflateNegotiated()
320: */
321:
322: static int
323: DeflateNegotiated(Bund b, int dir)
324: {
1.1.1.2 ! misho 325: (void)b;
! 326: (void)dir;
! 327:
1.1 misho 328: return 1;
329: }
330:
331: /*
332: * DeflateSubtractBloat()
333: */
334:
335: static int
336: DeflateSubtractBloat(Bund b, int size)
337: {
1.1.1.2 ! misho 338: (void)b;
! 339: (void)size;
! 340:
1.1 misho 341: return(size + CCP_OVERHEAD); /* Compression compensate header size */
342: }
343:
344: static int
345: DeflateStat(Context ctx, int dir)
346: {
347: Bund b = ctx->bund;
348: char path[NG_PATHSIZ];
349: struct ng_deflate_stats stats;
350: union {
351: u_char buf[sizeof(struct ng_mesg) + sizeof(stats)];
352: struct ng_mesg reply;
353: } u;
354:
355: switch (dir) {
356: case COMP_DIR_XMIT:
357: snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
358: NG_PPP_HOOK_COMPRESS);
359: break;
360: case COMP_DIR_RECV:
361: snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
362: NG_PPP_HOOK_DECOMPRESS);
363: break;
364: default:
365: assert(0);
366: }
367: if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0,
368: &u.reply, sizeof(u), NULL) < 0) {
369: Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
370: return(0);
371: }
372: memcpy(&stats, u.reply.data, sizeof(stats));
373: switch (dir) {
374: case COMP_DIR_XMIT:
375: Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
376: stats.InOctets,
377: stats.OutOctets,
378: ((stats.InOctets!=0)?
379: ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
380: 0));
381: Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
382: stats.FramesPlain,
383: stats.FramesComp,
384: stats.FramesUncomp);
385: Printf("\tErrors\t: %llu\r\n",
386: stats.Errors);
387: break;
388: case COMP_DIR_RECV:
389: Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
390: stats.OutOctets,
391: stats.InOctets,
392: ((stats.OutOctets!=0)?
393: ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
394: 0));
395: Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
396: stats.FramesPlain,
397: stats.FramesComp,
398: stats.FramesUncomp);
399: Printf("\tErrors\t: %llu\r\n",
400: stats.Errors);
401: break;
402: default:
403: assert(0);
404: }
405: return (0);
406: }
407:
408: #endif /* CCP_DEFLATE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>