From b85ea8667082555c4ae3a94650921584cfbcb3bb Mon Sep 17 00:00:00 2001 From: fendo Date: Thu, 7 Feb 2013 00:00:37 +0100 Subject: [PATCH] small performance improvement in download (internet -> customer) --- debian/changelog | 2 +- l2tpns.c | 38 +++++++++++------------ l2tpns.h | 1 + ppp.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ pppoe.c | 66 ++++++++++++++++++++++++++++++++++++++++ pppoe.h | 1 + 6 files changed, 166 insertions(+), 21 deletions(-) diff --git a/debian/changelog b/debian/changelog index 82031fe..3b4c2fa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,7 +2,7 @@ l2tpns (2.2.1-2fdn3.4) unstable; urgency=low * Add parameter to disable the send of the L2TP HELLO message (Apple compatibility). - -- Fernando Alves , 15 Jan 2013 15:17:22 +0100 + -- Fernando Alves Tue, 15 Jan 2013 15:17:22 +0100 l2tpns (2.2.1-2fdn3.3) unstable; urgency=low diff --git a/l2tpns.c b/l2tpns.c index 784e8cf..ee9f30b 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -1625,17 +1625,15 @@ void processipout(uint8_t *buf, int len) else { // Send it as one frame (NO MPPP Frame) - uint8_t *p = makeppp(fragbuf, sizeof(fragbuf), buf, len, s, t, PPPIP, 0, 0, 0); - if (!p) return; - tunnelsend(fragbuf, len + (p-fragbuf), t); // send it... + uint8_t *p = opt_makeppp(buf, len, s, t, PPPIP, 0, 0, 0); + tunnelsend(p, len + (buf-p), t); // send it... update_session_out_stat(s, sp, len); } } else { - uint8_t *p = makeppp(fragbuf, sizeof(fragbuf), buf, len, s, t, PPPIP, 0, 0, 0); - if (!p) return; - tunnelsend(fragbuf, len + (p-fragbuf), t); // send it... + uint8_t *p = opt_makeppp(buf, len, s, t, PPPIP, 0, 0, 0); + tunnelsend(p, len + (buf-p), t); // send it... update_session_out_stat(s, sp, len); } @@ -3969,9 +3967,9 @@ static void mainloop(void) { int i; uint8_t buf[65536]; - uint8_t *p = buf + 24; // for the hearder of the forwarded MPPP packet (see C_MPPP_FORWARD) + uint8_t *p = buf + 32; // for the hearder of the forwarded MPPP packet (see C_MPPP_FORWARD) // and the forwarded pppoe session - int size_bufp = sizeof(buf) - 24; + int size_bufp = sizeof(buf) - 32; clockt next_cluster_ping = 0; // send initial ping immediately struct epoll_event events[BASE_FDS + RADIUS_FDS + EXTRA_FDS]; int maxevent = sizeof(events)/sizeof(*events); @@ -4160,26 +4158,26 @@ static void mainloop(void) case FD_TYPE_CONTROL: // nsctl commands alen = sizeof(addr); - s = recvfromto(controlfd, buf, sizeof(buf), MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local); - if (s > 0) processcontrol(buf, s, &addr, alen, &local); + s = recvfromto(controlfd, p, size_bufp, MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local); + if (s > 0) processcontrol(p, s, &addr, alen, &local); n--; break; case FD_TYPE_DAE: // DAE requests alen = sizeof(addr); - s = recvfromto(daefd, buf, sizeof(buf), MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local); - if (s > 0) processdae(buf, s, &addr, alen, &local); + s = recvfromto(daefd, p, size_bufp, MSG_WAITALL, (struct sockaddr *) &addr, &alen, &local); + if (s > 0) processdae(p, s, &addr, alen, &local); n--; break; case FD_TYPE_RADIUS: // RADIUS response alen = sizeof(addr); - s = recvfrom(radfds[d->index], buf, sizeof(buf), MSG_WAITALL, (struct sockaddr *) &addr, &alen); + s = recvfrom(radfds[d->index], p, size_bufp, MSG_WAITALL, (struct sockaddr *) &addr, &alen); if (s >= 0 && config->cluster_iam_master) { if (addr.sin_addr.s_addr == config->radiusserver[0] || addr.sin_addr.s_addr == config->radiusserver[1]) - processrad(buf, s, d->index); + processrad(p, s, d->index); else LOG(3, 0, 0, "Dropping RADIUS packet from unknown source %s\n", fmtaddr(addr.sin_addr.s_addr, 0)); @@ -4197,8 +4195,8 @@ static void mainloop(void) case FD_TYPE_NETLINK: { - struct nlmsghdr *nh = (struct nlmsghdr *)buf; - s = netlink_recv(buf, sizeof(buf)); + struct nlmsghdr *nh = (struct nlmsghdr *)p; + s = netlink_recv(p, size_bufp); if (nh->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *errmsg = NLMSG_DATA(nh); @@ -4319,11 +4317,11 @@ static void mainloop(void) if (c >= config->multi_read_count) { #ifdef LAC - LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun %d cluster and %d rmlns packets\n", - config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts, udplac_pkts); + LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun %d cluster %d rmlns and %d pppoe packets\n", + config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts, udplac_pkts, pppoesess_pkts); #else - LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun and %d cluster packets\n", - config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts); + LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun %d cluster and %d pppoe packets\n", + config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts, pppoesess_pkts); #endif STAT(multi_read_exceeded); more++; diff --git a/l2tpns.h b/l2tpns.h index 98e605a..ffa09cc 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -899,6 +899,7 @@ void processipv6in(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l); void processccp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l); void sendchap(sessionidt s, tunnelidt t); uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits); +uint8_t *opt_makeppp(uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits); void sendlcp(sessionidt s, tunnelidt t); void send_ipin(sessionidt s, uint8_t *buf, int len); void sendccp(sessionidt s, tunnelidt t); diff --git a/ppp.c b/ppp.c index 5ed8563..e8c3b52 100644 --- a/ppp.c +++ b/ppp.c @@ -2607,6 +2607,85 @@ uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelid return b; } +// fill in a L2TP message with a PPP frame, +// returns start of PPP frame +//(note: THIS ROUTINE CAN WRITES TO p[-28]). +uint8_t *opt_makeppp(uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits) +{ + uint16_t hdr = 0x0002; // L2TP with no options + uint16_t type = mtype; + uint8_t *b = p; + + if (t == TUNNEL_ID_PPPOE) + { + return opt_pppoe_makeppp(p, l, s, t, mtype, prio, bid, mp_bits); + } + + // Check whether this session is part of multilink + if (bid) + { + if (bundle[bid].num_of_links > 1) + type = PPPMP; // Change PPP message type to the PPPMP + else + bid = 0; + } + + if (bid) + { + // Add the message type if this fragment has the begin bit set + if (mp_bits & MP_BEGIN) + { + b -= 2; + *(uint16_t *) b = htons(mtype); // Message type + } + + // Set the sequence number and (B)egin (E)nd flags + if (session[s].mssf) + { + // Set the multilink bits + uint16_t bits_send = mp_bits; + b -= 2; + *(uint16_t *) b = htons((bundle[bid].seq_num_t & 0x0FFF)|bits_send); + } + else + { + b -= 4; + *(uint32_t *) b = htonl(bundle[bid].seq_num_t); + // Set the multilink bits + *b = mp_bits; + } + + bundle[bid].seq_num_t++; + } + + if (type < 0x100 && session[s].flags & SESSION_PFC) + { + b--; + *b = type; + } + else + { + b -= 2; + *(uint16_t *) b = htons(type); + } + + if (type == PPPLCP || !(session[s].flags & SESSION_ACFC)) + { + b -= 2; + *(uint16_t *) b = htons(0xFF03); // HDLC header + } + + if (prio) hdr |= 0x0100; // set priority bit + b -= 2; + *(uint16_t *) b = htons(session[s].far); // session + b -= 2; + *(uint16_t *) b = htons(tunnel[t].far); // tunnel + b -= 2; + *(uint16_t *) b = htons(hdr); + + return b; +} + static int add_lcp_auth(uint8_t *b, int size, int authtype) { int len = 0; diff --git a/pppoe.c b/pppoe.c index 882e0c1..4b196ea 100644 --- a/pppoe.c +++ b/pppoe.c @@ -763,6 +763,72 @@ uint8_t *pppoe_makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tu return b; } +// fill in a PPPOE message with a PPP frame, +// returns start of PPP frame +//(note: THIS ROUTINE WRITES TO p[-28]). +uint8_t *opt_pppoe_makeppp(uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits) +{ + uint16_t type = mtype; + uint16_t hdrlen = l; + uint8_t *b = p; + struct pppoe_hdr *hdr; + + if (t != TUNNEL_ID_PPPOE) + return NULL; + + // Check whether this session is part of multilink + if (bid) + { + if (bundle[bid].num_of_links > 1) + type = PPPMP; // Change PPP message type to the PPPMP + else + bid = 0; + } + + if (bid) + { + // Add the message type if this fragment has the begin bit set + if (mp_bits & MP_BEGIN) + { + b -= 2; + *(uint16_t *) b = htons(mtype); // Message type + } + + // Set the sequence number and (B)egin (E)nd flags + if (session[s].mssf) + { + // Set the multilink bits + uint16_t bits_send = mp_bits; + b -= 2; + *(uint16_t *) b = htons((bundle[bid].seq_num_t & 0x0FFF)|bits_send); + } + else + { + b -= 4; + *(uint32_t *) b = htonl(bundle[bid].seq_num_t); + // Set the multilink bits + *b = mp_bits; + } + + bundle[bid].seq_num_t++; + } + + b -= 2; + *(uint16_t *) b = htons(type); + + // Size ppp packet + hdrlen += (p - b); + + // 14 bytes ethernet Header + 6 bytes header pppoe + b -= (ETH_HLEN + sizeof(*hdr)); + setup_header(b, config->pppoe_hwaddr, session[s].src_hwaddr, CODE_SESS, s, ETH_P_PPP_SES); + hdr = (struct pppoe_hdr *)(b + ETH_HLEN); + // Store length on header pppoe + hdr->length = hdrlen; + + return b; +} + // pppoe discovery recv data void process_pppoe_disc(uint8_t *pack, int size) { diff --git a/pppoe.h b/pppoe.h index 62a8208..a4dabc8 100644 --- a/pppoe.h +++ b/pppoe.h @@ -11,6 +11,7 @@ void process_pppoe_sess(uint8_t *pack, int size); void pppoe_sess_send(const uint8_t *pack, uint16_t l, tunnelidt t); uint8_t *pppoe_makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits); +uint8_t *opt_pppoe_makeppp(uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits); void pppoe_shutdown_session(sessionidt s); void pppoe_forwardto_session_pppoe(uint8_t *pack, int size, sessionidt sess, uint16_t proto); void pppoe_process_forward(uint8_t *pack, int size, in_addr_t addr); -- 2.20.1