Сеpвеp VPN есть такой, чтобы с Радиyсом дpyжил?

From
Slawa Olhovchenkov (2:5030/500)
To
Alexander Motin
Date
2007-01-16T15:27:16Z
Area
RU.UNIX.BSD
Hello Alexander!

16 Jan 07, Alexander Motin writes to Slawa Olhovchenkov:

 >>  AM> Халявы не будет. В ядре не хватает пары файликов для поддержки MPPC.
 >>  AM> Покупают их у Hi/Fn (hifn.com), но судя по тому, как они отвечают на
 >>  AM> письма надежды на это мало.
 >>
 >> Ты уверен что не хватает?

 AM> Уверен. Чтоб работала компрессия, надо ng_mppc собрать с опцией
 AM> NETGRAPH_MPPC_COMPRESSION. А он при этом потребует файлик net/mppc.h с
 AM> функами MPPC_Compress и MPPC_Decompress. А его нет.

Как нет?! А что же я вижу в репозитории?

ng_mppc_compress(node_p node, struct mbuf *m, struct mbuf **resultp)
{
    const priv_p priv = NG_NODE_PRIVATE(node);
    struct ng_mppc_dir *const d = &priv->xmit;
    u_char *inbuf, *outbuf;
    int outlen, inlen;
    u_int16_t header;

    /* Initialize */
    *resultp = NULL;
    header = d->cc;
    if (d->flushed) {
        header |= MPPC_FLAG_FLUSHED;
        d->flushed = 0;
    }

    /* Work with contiguous regions of memory */
    inlen = m->m_pkthdr.len;
    MALLOC(inbuf, u_char *, inlen, M_NETGRAPH_MPPC, M_NOWAIT);
    if (inbuf == NULL)
        return (ENOMEM);
    m_copydata(m, 0, inlen, (caddr_t)inbuf);
    if ((d->cfg.bits & MPPC_BIT) != 0)
        outlen = MPPC_MAX_BLOWUP(inlen);
    else
        outlen = MPPC_HDRLEN + inlen;
    MALLOC(outbuf, u_char *, outlen, M_NETGRAPH_MPPC, M_NOWAIT);
    if (outbuf == NULL) {
        FREE(inbuf, M_NETGRAPH_MPPC);
        return (ENOMEM);
    }

    /* Compress "inbuf" into "outbuf" (if compression enabled) */
#ifdef NETGRAPH_MPPC_COMPRESSION
    if ((d->cfg.bits & MPPC_BIT) != 0) {
        u_short flags = MPPC_MANDATORY_COMPRESS_FLAGS;
        u_char *source, *dest;
        u_long sourceCnt, destCnt;
        int rtn;

        /* Prepare to compress */
        source = inbuf;
        sourceCnt = inlen;
        dest = outbuf + MPPC_HDRLEN;
        destCnt = outlen - MPPC_HDRLEN;
        if ((d->cfg.bits & MPPE_STATELESS) == 0)
            flags |= MPPC_SAVE_HISTORY;

        /* Compress */
        rtn = MPPC_Compress(&source, &dest, &sourceCnt,
            &destCnt, d->history, flags, 0);

        /* Check return value */
        KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__));
        if ((rtn & MPPC_EXPANDED) == 0
            && (rtn & MPPC_COMP_OK) == MPPC_COMP_OK) {
            outlen -= destCnt;
            header |= MPPC_FLAG_COMPRESSED;
            if ((rtn & MPPC_RESTART_HISTORY) != 0)
                header |= MPPC_FLAG_RESTART;
        }
        d->flushed = (rtn & MPPC_EXPANDED) != 0
            || (flags & MPPC_SAVE_HISTORY) == 0;
    }
#endif

    /* If we did not compress this packet, copy it to output buffer */
    if ((header & MPPC_FLAG_COMPRESSED) == 0) {
        bcopy(inbuf, outbuf + MPPC_HDRLEN, inlen);
        outlen = MPPC_HDRLEN + inlen;
    }
    FREE(inbuf, M_NETGRAPH_MPPC);

    /* Always set the flushed bit in stateless mode */
    if ((d->cfg.bits & MPPE_STATELESS) != 0)
        header |= MPPC_FLAG_FLUSHED;

    /* Now encrypt packet (if encryption enabled) */
#ifdef NETGRAPH_MPPC_ENCRYPTION
    if ((d->cfg.bits & MPPE_BITS) != 0) {

        /* Set header bits; need to reset key if we say we did */
        header |= MPPC_FLAG_ENCRYPTED;
        if ((header & MPPC_FLAG_FLUSHED) != 0)
            rc4_init(&d->rc4, d->key, KEYLEN(d->cfg.bits));

        /* Update key if it's time */
        if ((d->cfg.bits & MPPE_STATELESS) != 0
            || (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) {
              ng_mppc_updatekey(d->cfg.bits,
                  d->cfg.startkey, d->key, &d->rc4);
        }

        /* Encrypt packet */
        rc4_crypt(&d->rc4, outbuf + MPPC_HDRLEN,
            outbuf + MPPC_HDRLEN, outlen - MPPC_HDRLEN);
    }
#endif

    /* Update sequence number */
    d->cc++;

    /* Install header */
    *((u_int16_t *)outbuf) = htons(header);

    /* Return packet in an mbuf */
    *resultp = m_devget((caddr_t)outbuf, outlen, 0, NULL, NULL);
    FREE(outbuf, M_NETGRAPH_MPPC);
    return (*resultp == NULL ? ENOBUFS : 0);
}

/*
 * Decompress/decrypt packet and put the result in a new mbuf at *resultp.
 * The original mbuf is not free'd.
 */
static int
ng_mppc_decompress(node_p node, struct mbuf *m, struct mbuf **resultp)
{
    const priv_p priv = NG_NODE_PRIVATE(node);
    struct ng_mppc_dir *const d = &priv->recv;
    u_int16_t header, cc;
    u_int numLost;
    u_char *buf;
    int len;

    /* Pull off header */
    if (m->m_pkthdr.len < MPPC_HDRLEN)
        return (EINVAL);
    m_copydata(m, 0, MPPC_HDRLEN, (caddr_t)&header);
    header = ntohs(header);
    cc = (header & MPPC_CCOUNT_MASK);

    /* Copy payload into a contiguous region of memory */
    len = m->m_pkthdr.len - MPPC_HDRLEN;
    MALLOC(buf, u_char *, len, M_NETGRAPH_MPPC, M_NOWAIT);
    if (buf == NULL)
        return (ENOMEM);
    m_copydata(m, MPPC_HDRLEN, len, (caddr_t)buf);

    /* Check for an unexpected jump in the sequence number */
    numLost = ((cc - d->cc) & MPPC_CCOUNT_MASK);

    /* If flushed bit set, we can always handle packet */
    if ((header & MPPC_FLAG_FLUSHED) != 0) {
#ifdef NETGRAPH_MPPC_COMPRESSION
        if (d->history != NULL)
            MPPC_InitDecompressionHistory(d->history);
#endif
#ifdef NETGRAPH_MPPC_ENCRYPTION
        if ((d->cfg.bits & MPPE_BITS) != 0) {
            u_int rekey;

            /* How many times are we going to have to re-key? */
            rekey = ((d->cfg.bits & MPPE_STATELESS) != 0) ?
                numLost : (numLost / (MPPE_UPDATE_MASK + 1));
            if (rekey > MPPE_MAX_REKEY) {
                log(LOG_ERR, "%s: too many (%d) packets"
                    " dropped, disabling node %p!",
                    __func__, numLost, node);
                priv->recv.cfg.enable = 0;
                goto failed;
            }

            /* Re-key as necessary to catch up to peer */
            while (d->cc != cc) {
                if ((d->cfg.bits & MPPE_STATELESS) != 0
                    || (d->cc & MPPE_UPDATE_MASK)
                      == MPPE_UPDATE_FLAG) {
                    ng_mppc_updatekey(d->cfg.bits,
                        d->cfg.startkey, d->key, &d->rc4);
                }
                d->cc++;
            }

            /* Reset key (except in stateless mode, see below) */
            if ((d->cfg.bits & MPPE_STATELESS) == 0)
                rc4_init(&d->rc4, d->key, KEYLEN(d->cfg.bits));
        }
#endif
        d->cc = cc;     /* skip over lost seq numbers */
        numLost = 0;        /* act like no packets were lost */
    }

    /* Can't decode non-sequential packets without a flushed bit */
    if (numLost != 0)
        goto failed;

    /* Decrypt packet */
    if ((header & MPPC_FLAG_ENCRYPTED) != 0) {

        /* Are we not expecting encryption? */
        if ((d->cfg.bits & MPPE_BITS) == 0) {
            log(LOG_ERR, "%s: rec'd unexpectedly %s packet",
                __func__, "encrypted");
            goto failed;
        }

#ifdef NETGRAPH_MPPC_ENCRYPTION
        /* Update key if it's time (always in stateless mode) */
        if ((d->cfg.bits & MPPE_STATELESS) != 0
            || (d->cc & MPPE_UPDATE_MASK) == MPPE_UPDATE_FLAG) {
            ng_mppc_updatekey(d->cfg.bits,
                d->cfg.startkey, d->key, &d->rc4);
        }

        /* Decrypt packet */
        rc4_crypt(&d->rc4, buf, buf, len);
#endif
    } else {

        /* Are we expecting encryption? */
        if ((d->cfg.bits & MPPE_BITS) != 0) {
            log(LOG_ERR, "%s: rec'd unexpectedly %s packet",
                __func__, "unencrypted");
            goto failed;
        }
    }

    /* Update coherency count for next time (12 bit arithmetic) */
    d->cc++;

    /* Check for unexpected compressed packet */
    if ((header & MPPC_FLAG_COMPRESSED) != 0
        && (d->cfg.bits & MPPC_BIT) == 0) {
        log(LOG_ERR, "%s: rec'd unexpectedly %s packet",
            __func__, "compressed");
failed:
        FREE(buf, M_NETGRAPH_MPPC);
        return (EINVAL);
    }

#ifdef NETGRAPH_MPPC_COMPRESSION
    /* Decompress packet */
    if ((header & MPPC_FLAG_COMPRESSED) != 0) {
        int flags = MPPC_MANDATORY_DECOMPRESS_FLAGS;
        u_char *decompbuf, *source, *dest;
        u_long sourceCnt, destCnt;
        int decomplen, rtn;

        /* Allocate a buffer for decompressed data */
        MALLOC(decompbuf, u_char *, MPPC_DECOMP_BUFSIZE
            + MPPC_DECOMP_SAFETY, M_NETGRAPH_MPPC, M_NOWAIT);
        if (decompbuf == NULL) {
            FREE(buf, M_NETGRAPH_MPPC);
            return (ENOMEM);
        }
        decomplen = MPPC_DECOMP_BUFSIZE;

        /* Prepare to decompress */
        source = buf;
        sourceCnt = len;
        dest = decompbuf;
        destCnt = decomplen;
        if ((header & MPPC_FLAG_RESTART) != 0)
            flags |= MPPC_RESTART_HISTORY;

        /* Decompress */
        rtn = MPPC_Decompress(&source, &dest,
            &sourceCnt, &destCnt, d->history, flags);

        /* Check return value */
        KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__));
        if ((rtn & MPPC_DEST_EXHAUSTED) != 0
            || (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) {
            log(LOG_ERR, "%s: decomp returned 0x%x",
                __func__, rtn);
            FREE(decompbuf, M_NETGRAPH_MPPC);
            goto failed;
        }

        /* Replace compressed data with decompressed data */
        FREE(buf, M_NETGRAPH_MPPC);
        buf = decompbuf;
        len = decomplen - destCnt;
    }
#endif

    /* Return result in an mbuf */
    *resultp = m_devget((caddr_t)buf, len, 0, NULL, NULL);
    FREE(buf, M_NETGRAPH_MPPC);
    return (*resultp == NULL ? ENOBUFS : 0);
}



... См. рис. 1
--- GoldED+/BSD 1.1.5
 * Origin:  (2:5030/500)
SEEN-BY: 50/12 203 400/814 450/186 1024 451/30 469/418 550/196 4614/20 4635/4
SEEN-BY: 5000/5000 5011/13 5012/46 5015/28 5019/26 5020/154 175 400 545 549
SEEN-BY: 5020/758 1523 1604 1630 2142 2238 2395 2450 2590 2871 4441 5021/3 29
SEEN-BY: 5022/128 5025/3 750 5027/12 5029/32 5030/500 556 966 1900 1957 2828
SEEN-BY: 5031/47 70 5035/38 5040/47 5042/13 5045/7 5049/50 97 5054/1 4 8 9 11
SEEN-BY: 5054/28 35 36 37 45 66 67 70 75 84 85 5059/9 37 5062/1 10 5063/3
SEEN-BY: 5064/7 5076/1 5077/70 5080/80 1003 5082/6 5083/21 5084/9 5085/13
SEEN-BY: 5090/108 5094/4 5095/20 5096/18 5099/11 6001/10
PATH: 5030/500 5020/4441 545 5054/1 37