Annotation of embedaddon/mpd/src/ccp_deflate.c, revision 1.1.1.1

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: 
                    104:     id = NgGetNodeID(-1, path);
                    105:     if (dir == COMP_DIR_XMIT) {
                    106:        b->ccp.comp_node_id = id;
                    107:     } else {
                    108:        b->ccp.decomp_node_id = id;
                    109:     }
                    110: 
                    111:     /* Configure DEFLATE node */
                    112:     snprintf(path, sizeof(path), "[%x]:", id);
                    113:     if (NgSendMsg(gCcpCsock, path,
                    114:            NGM_DEFLATE_COOKIE, NGM_DEFLATE_CONFIG, &conf, sizeof(conf)) < 0) {
                    115:        Perror("[%s] can't config %s node at %s",
                    116:            b->name, NG_DEFLATE_NODE_TYPE, path);
                    117:        NgFuncShutdownNode(gCcpCsock, b->name, path);
                    118:        return(-1);
                    119:     }
                    120: 
                    121:     return 0;
                    122: }
                    123: 
                    124: /*
                    125:  * DeflateConfigure()
                    126:  */
                    127: 
                    128: static int
                    129: DeflateConfigure(Bund b)
                    130: {
                    131:     CcpState   const ccp = &b->ccp;
                    132:     DeflateInfo        const deflate = &ccp->deflate;
                    133:   
                    134:     deflate->xmit_windowBits=15;
                    135:     deflate->recv_windowBits=0;
                    136:   
                    137:     return(0);
                    138: }
                    139: 
                    140: /*
                    141:  * DeflateCleanup()
                    142:  */
                    143: 
                    144: static char *
                    145: DeflateDescribe(Bund b, int dir, char *buf, size_t len)
                    146: {
                    147:     CcpState   const ccp = &b->ccp;
                    148:     DeflateInfo        const deflate = &ccp->deflate;
                    149: 
                    150:     switch (dir) {
                    151:        case COMP_DIR_XMIT:
                    152:            snprintf(buf, len, "win %d", deflate->xmit_windowBits);
                    153:            break;
                    154:        case COMP_DIR_RECV:
                    155:            snprintf(buf, len, "win %d", deflate->recv_windowBits);
                    156:            break;
                    157:        default:
                    158:            assert(0);
                    159:            return(NULL);
                    160:     }
                    161:     return (buf);
                    162: }
                    163: 
                    164: /*
                    165:  * DeflateCleanup()
                    166:  */
                    167: 
                    168: void
                    169: DeflateCleanup(Bund b, int dir)
                    170: {
                    171:     char               path[NG_PATHSIZ];
                    172: 
                    173:     /* Remove node */
                    174:     if (dir == COMP_DIR_XMIT) {
                    175:        snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
                    176:        b->ccp.comp_node_id = 0;
                    177:     } else {
                    178:        snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
                    179:        b->ccp.decomp_node_id = 0;
                    180:     }
                    181:     NgFuncShutdownNode(gCcpCsock, b->name, path);
                    182: }
                    183: 
                    184: /*
                    185:  * DeflateRecvResetReq()
                    186:  */
                    187: 
                    188: static Mbuf
                    189: DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
                    190: {
                    191:     char               path[NG_PATHSIZ];
                    192:     /* Forward ResetReq to the DEFLATE compression node */
                    193:     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
                    194:     if (NgSendMsg(gCcpCsock, path,
                    195:            NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
                    196:        Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
                    197:     }
                    198:     return(NULL);
                    199: }
                    200: 
                    201: /*
                    202:  * DeflateSendResetReq()
                    203:  */
                    204: 
                    205: static Mbuf
                    206: DeflateSendResetReq(Bund b)
                    207: {
                    208:   return(NULL);
                    209: }
                    210: 
                    211: /*
                    212:  * DeflateRecvResetAck()
                    213:  */
                    214: 
                    215: static void
                    216: DeflateRecvResetAck(Bund b, int id, Mbuf bp)
                    217: {
                    218:     char               path[NG_PATHSIZ];
                    219:     /* Forward ResetReq to the DEFLATE compression node */
                    220:     snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
                    221:     if (NgSendMsg(gCcpCsock, path,
                    222:            NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
                    223:        Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
                    224:     }
                    225: }
                    226: 
                    227: /*
                    228:  * DeflateBuildConfigReq()
                    229:  */
                    230: 
                    231: static u_char *
                    232: DeflateBuildConfigReq(Bund b, u_char *cp, int *ok)
                    233: {
                    234:   CcpState     const ccp = &b->ccp;
                    235:   DeflateInfo  const deflate = &ccp->deflate;
                    236:   u_int16_t    opt;
                    237:   
                    238:   if (deflate->xmit_windowBits > 0) {
                    239:     opt = ((deflate->xmit_windowBits-8)<<12) + (8<<8) + (0<<2) + 0;
                    240:   
                    241:     cp = FsmConfValue(cp, CCP_TY_DEFLATE, -2, &opt);
                    242:     *ok = 1;
                    243:   }
                    244:   return (cp);
                    245: }
                    246: 
                    247: /*
                    248:  * DeflateDecodeConfigReq()
                    249:  */
                    250: 
                    251: static void
                    252: DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
                    253: {
                    254:     Bund       b = (Bund)fp->arg;
                    255:   CcpState     const ccp = &b->ccp;
                    256:   DeflateInfo  const deflate = &ccp->deflate;
                    257:   u_int16_t     o;
                    258:   u_char       window, method, chk;
                    259: 
                    260:   /* Sanity check */
                    261:   if (opt->len != 4) {
                    262:     Log(LG_CCP, ("[%s]     bogus length %d", b->name, opt->len));
                    263:     if (mode == MODE_REQ)
                    264:       FsmRej(fp, opt);
                    265:     return;
                    266:   }
                    267: 
                    268:   /* Get bits */
                    269:   memcpy(&o, opt->data, 2);
                    270:   o = ntohs(o);
                    271:   window = (o>>12)&0x000F;
                    272:   method = (o>>8)&0x000F;
                    273:   chk = o&0x0003;
                    274: 
                    275:   /* Display it */
                    276:   Log(LG_CCP, ("[%s]     0x%04x: w:%d, m:%d, c:%d", b->name, o, window, method, chk));
                    277: 
                    278:   /* Deal with it */
                    279:   switch (mode) {
                    280:     case MODE_REQ:
                    281:        if ((window > 0) && (window<=7) && (method == 8) && (chk == 0)) {
                    282:            deflate->recv_windowBits = window + 8;
                    283:            FsmAck(fp, opt);
                    284:        } else {
                    285:            o = htons((7<<12) + (8<<8) + (0<<2) + 0);
                    286:            memcpy(opt->data, &o, 2);
                    287:            FsmNak(fp, opt);
                    288:        }
                    289:       break;
                    290: 
                    291:     case MODE_NAK:
                    292:        if ((window > 0) && (window<=7) && (method == 8) && (chk == 0))
                    293:            deflate->xmit_windowBits = window + 8;
                    294:        else {
                    295:            deflate->xmit_windowBits = 0;
                    296:        }
                    297:       break;
                    298:   }
                    299: }
                    300: 
                    301: /*
                    302:  * DeflateNegotiated()
                    303:  */
                    304: 
                    305: static int
                    306: DeflateNegotiated(Bund b, int dir)
                    307: {
                    308:   return 1;
                    309: }
                    310: 
                    311: /*
                    312:  * DeflateSubtractBloat()
                    313:  */
                    314: 
                    315: static int
                    316: DeflateSubtractBloat(Bund b, int size)
                    317: {
                    318:   return(size + CCP_OVERHEAD);  /* Compression compensate header size */
                    319: }
                    320: 
                    321: static int
                    322: DeflateStat(Context ctx, int dir) 
                    323: {
                    324:     Bund                       b = ctx->bund;
                    325:     char                       path[NG_PATHSIZ];
                    326:     struct ng_deflate_stats    stats;
                    327:     union {
                    328:        u_char                  buf[sizeof(struct ng_mesg) + sizeof(stats)];
                    329:        struct ng_mesg          reply;
                    330:     }                          u;
                    331: 
                    332:     switch (dir) {
                    333:        case COMP_DIR_XMIT:
                    334:            snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
                    335:                NG_PPP_HOOK_COMPRESS);
                    336:            break;
                    337:        case COMP_DIR_RECV:
                    338:            snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
                    339:                NG_PPP_HOOK_DECOMPRESS);
                    340:            break;
                    341:        default:
                    342:            assert(0);
                    343:     }
                    344:     if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0, 
                    345:        &u.reply, sizeof(u), NULL) < 0) {
                    346:            Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
                    347:            return(0);
                    348:     }
                    349:     memcpy(&stats, u.reply.data, sizeof(stats));
                    350:     switch (dir) {
                    351:        case COMP_DIR_XMIT:
                    352:            Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
                    353:                stats.InOctets,
                    354:                stats.OutOctets,
                    355:                ((stats.InOctets!=0)?
                    356:                    ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
                    357:                    0));
                    358:            Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
                    359:                stats.FramesPlain,
                    360:                stats.FramesComp,
                    361:                stats.FramesUncomp);
                    362:            Printf("\tErrors\t: %llu\r\n",
                    363:                stats.Errors);
                    364:            break;
                    365:        case COMP_DIR_RECV:
                    366:            Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
                    367:                stats.OutOctets,
                    368:                stats.InOctets,
                    369:                ((stats.OutOctets!=0)?
                    370:                    ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
                    371:                    0));
                    372:            Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
                    373:                stats.FramesPlain,
                    374:                stats.FramesComp,
                    375:                stats.FramesUncomp);
                    376:            Printf("\tErrors\t: %llu\r\n",
                    377:                stats.Errors);
                    378:            break;
                    379:        default:
                    380:            assert(0);
                    381:     }
                    382:     return (0);
                    383: }
                    384: 
                    385: #endif /* CCP_DEFLATE */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>