| Age | Commit message (Collapse) | Author |
|
|
|
decode_avp() only checked the 2 bytes length prefix of the Hidden AVP
Subformat when the ciphered attribute spanned more than one MD5 block.
For an attribute of at most 16 bytes it deciphered the single block and
returned straight away, leaving l2tp_recv() to take the prefix at face
value:
orig_avp_len = ntohs(*(uint16_t *)avp->val) + sizeof(*avp);
...
attr->length = orig_avp_len - sizeof(*avp);
That prefix is an output of the cipher, so a peer which does not know
the secret (i.e. anyone able to reach the L2TP socket, no handshake
needed beyond a preceding Random-Vector AVP) turns it into 16 random
bits. Worse than an over-read: orig_avp_len is a uint16_t, so a prefix
of 0xffff wraps to 5, attr->length becomes -1, and the ATTR_TYPE_STRING
and ATTR_TYPE_OCTETS cases then run
attr->val.string = _malloc(attr->length + 1); /* _malloc(0) */
memcpy(attr->val.string, orig_avp_val, attr->length); /* SIZE_MAX */
that is an unbounded memcpy() into a zero sized allocation. Remotely
triggerable heap corruption on any tunnel with a secret configured. The
accel-ppp encoder always pads hidden AVPs by at least 16 bytes, so it
never produces an attribute short enough to reach this path; only a
crafted packet does.
Fix it at the source rather than at the call site: decode_avp() now
returns the deciphered length through an output parameter, and the
length is bounded against the room actually available in the received
AVP on every path out of the function, single block included. Callers
can no longer re-derive it from the AVP body and get it wrong, and the
existing multi-block check keeps guarding the deciphering loop itself.
Add packet_test.c, a standalone test which drives the real parser
through a real UDP socket: hand-crafted packets cover the length prefix
checks (including the boundaries of what fits and the single block path
the encoder cannot produce), and l2tp_packet_send()/l2tp_recv() round
trips cover the multi-block cipher and the unaligned AVP accessors. It
reproduces the corruption above under ASan on unpatched code. Wire it,
and the so far unused bitpool_test.c, into the ASAN/UBSAN workflow.
Inspired by the equivalent hardening in accel-ppp-ng (commit a8ca0f3f),
which bounds the length at the call site; the fix here is placed inside
decode_avp() and covered by a regression test.
|
|
AVPs are packed back to back in the receive buffer, so the offset of any
given AVP is the sum of the lengths of all the AVPs before it, i.e. a
value the peer picks. Casting avp->val to uint16_t/uint32_t/uint64_t
therefore dereferences a pointer with an arbitrary alignment, which is
undefined behaviour, is caught by -fsanitize=alignment, and is only
harmless on x86 by accident. The same applies to the send path, where
the AVPs being built are laid out the same way.
Introduce unaligned_{ntohs,ntohl,be64toh}() and their store
counterparts, all memcpy() based, and use them for every multi-byte
field read out of or written into an AVP body. Accesses to the members
of struct l2tp_avp_t itself are fine as it is declared packed.
memxor() had the same problem, in a worse form: it cast both of its
uint8_t pointers to uintmax_t and walked them word by word. Since it is
only ever called on MD5 sized chunks, replace it with a plain byte loop
which compilers vectorize just as well, and which no longer breaks
strict aliasing either.
No functional change intended, this is a portability and UB fix; it also
removes a source of noise for the s390x (big endian) CI job.
|
|
|
|
Group the core session starting, active, and finishing statistics behind the private ap_session_stat storage in session.c instead of exposing writable counters through ap_session.h. This keeps ownership inside the session core while preserving the existing CLI and ACCEL-PPP-MIB counter semantics.
Route session counter updates through ap_session_stat_*() helpers. Session start, activation, termination, finish, and shutdown-idle paths no longer open-code individual counter increments/decrements; the update policy now lives beside the session-owned storage and uses relaxed atomic operations for the simple state counters.
Make the CLI show-stat path render from a local snapshot and convert the PPP SNMP starting/active/finishing scalars from watched raw pointers to scalar handlers. PPP controllers now read max-session limits through ap_session_stat_starting() and ap_session_stat_active(), removing external direct access to ap_session_stat.
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
|
|
Group the L2TP tunnel, control-session, and data-session statistics in struct l2tp_stat_t and keep the storage private to l2tp.c instead of spreading writable stat_* globals through the module. This keeps the ownership boundary in the L2TP control code while preserving the existing CLI and ACCEL-PPP-MIB counter semantics.
Route counter updates through l2tp_stat_*() helpers. Tunnel, control-session, and data-session state transitions no longer open-code individual counter increments/decrements; the update policy now lives beside the L2TP-owned storage and uses relaxed atomic operations for the simple state counters.
Make the CLI show-stat path render from a local snapshot and convert the L2TP SNMP starting/active scalars from watched raw pointers to scalar handlers. SNMP now reads through l2tp_stat_starting() and l2tp_stat_active(), removing the old l2tp_get_stat() pointer escape hatch.
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
|
|
|
|
Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
|
|
Fix issues introduced in 88a2ebdb:
- Fix type declaration: uint8_t *calling[254] declared an array of 254
pointers instead of an array of 254 bytes. Remove erroneous asterisks.
- Fix buffer overflow vulnerability: L2TP AVP values can be up to 1017
bytes (L2TP_AVP_LEN_MASK - sizeof(avp_header)), but buffers were only
254(*4?) bytes. A malicious packet could cause stack buffer overflow.
Use L2TP_AVP_LEN_MASK (1023) for buffer size to handle maximum AVP length.
- Remove useless NULL checks: Stack-allocated arrays can never be NULL,
causing compiler warnings. The existence check is n > 0 / m > 1.
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
|
|
|
|
build: fix compile errors on GCC 14
|
|
It is logical, that function should remain same,
not changed to free.
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
|
|
This patch fixes compile errors on GCC 14 like the following
/root/accel-ppp/accel-pppd/radius/packet.c: In function 'rad_packet_recv':
/root/accel-ppp/accel-pppd/radius/packet.c:142:72: error: passing argument 5 of 'recvfrom' from incompatible pointer type [-Wincompatible-pointer-types]
142 | n = recvfrom(fd, pack->buf, REQ_LENGTH_MAX, 0, addr, &addr_len);
| ^~~~
| |
| struct sockaddr_in *
In file included from /usr/include/netinet/in.h:10,
from /usr/include/arpa/inet.h:9,
from /root/accel-ppp/accel-pppd/radius/packet.c:10:
/usr/include/sys/socket.h:397:55: note: expected 'struct sockaddr * restrict' but argument is of type 'struct sockaddr_in *'
Reference: https://gcc.gnu.org/gcc-14/porting_to.html
|
|
Thanks for hints Alpine Linux project and their patches:
https://git.alpinelinux.org/aports/tree/community/accel-ppp?h=master
We can adjust a bit code and cmake config files to make accel-ppp
buildable under musl "as is".
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
|
|
|
|
* Fix errors found by valgrind
==12312== Syscall param sendmsg(msg.msg_iov[0]) points to uninitialised byte(s)
==12312== at 0x486CCF0: sendmsg (in /lib/libpthread-2.22.so)
==12312== by 0x12F57F: rtnl_talk (libnetlink.c:316)
==12312== by 0x132DA3: genl_resolve_mcg (genl.c:52)
==12312== by 0x484E1CB: init (vlan_mon.c:528)
==12312== by 0x484CDC0: vlan_mon_register_proto (vlan_mon.c:48)
==12312== by 0x510B763: load_vlan_mon (pppoe.c:1914)
==12312== by 0x510BFF2: load_config (pppoe.c:2064)
==12312== by 0x510C22A: pppoe_init (pppoe.c:2108)
==12312== by 0x483E9EB: triton_load_modules (triton.c:704)
==12312== by 0x1384B2: main (main.c:339)
==12312== Address 0xbedacdd8 is on thread 1's stack
==12312== in frame #2, created by genl_resolve_mcg (genl.c:23)
==12312== 15 bytes in 1 blocks are definitely lost in loss record 352 of 836
==12312== at 0x482A9A9: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==12312== by 0x4B97524: strdup (in /lib/libc-2.22.so)
==12312== by 0x12C30C: init (telnet.c:769)
==12312== by 0x483E9EB: triton_load_modules (triton.c:704)
==12312== by 0x1384B2: main (main.c:339)
==12312==
==12312== 15 bytes in 1 blocks are definitely lost in loss record 353 of 836
==12312== at 0x482A9A9: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==12312== by 0x4B97524: strdup (in /lib/libc-2.22.so)
==12312== by 0x12D60A: init (tcp.c:392)
==12312== by 0x483E9EB: triton_load_modules (triton.c:704)
==12312== by 0x1384B2: main (main.c:339)
* Fix another warnings by cppcheck
[accel-pppd/ctrl/ipoe/arp.c:256]: (error) Uninitialized variable: n
[accel-pppd/ctrl/pppoe/mac_filter.c:90]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:90]: (warning) %x in format string (no. 2) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:90]: (warning) %x in format string (no. 3) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:90]: (warning) %x in format string (no. 4) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:90]: (warning) %x in format string (no. 5) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:90]: (warning) %x in format string (no. 6) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:129]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:129]: (warning) %x in format string (no. 2) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:129]: (warning) %x in format string (no. 3) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:129]: (warning) %x in format string (no. 4) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:129]: (warning) %x in format string (no. 5) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:129]: (warning) %x in format string (no. 6) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:158]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:158]: (warning) %x in format string (no. 2) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:158]: (warning) %x in format string (no. 3) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:158]: (warning) %x in format string (no. 4) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:158]: (warning) %x in format string (no. 5) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/mac_filter.c:158]: (warning) %x in format string (no. 6) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ctrl/pppoe/pppoe.c:738]: (warning) Possible null pointer dereference
[accel-pppd/ipv6/dhcpv6.c:911]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'int *'.
[accel-pppd/ipv6/dhcpv6.c:911]: (warning) %x in format string (no. 2) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ipv6/dhcpv6.c:911]: (warning) %x in format string (no. 3) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ipv6/dhcpv6.c:911]: (warning) %x in format string (no. 4) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/libnetlink/libnetlink.c:515]: (warning) Possible null pointer dereference
[accel-pppd/ppp/ipv6cp_opt_intfid.c:185]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ppp/ipv6cp_opt_intfid.c:298]: (warning) %x in format string (no. 1) requires 'unsigned int *' but the argument type is 'int *'.
[accel-pppd/ppp/ipv6cp_opt_intfid.c:298]: (warning) %x in format string (no. 2) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ppp/ipv6cp_opt_intfid.c:298]: (warning) %x in format string (no. 3) requires 'unsigned int *' but the argument type is 'signed int *'.
[accel-pppd/ppp/ipv6cp_opt_intfid.c:298]: (warning) %x in format string (no. 4) requires 'unsigned int *' but the argument type is 'signed int *'.
* Suppress compiler warnings
* Fix locking errors
/opt/pvs/accel-ppp/accel-pppd/extra/pppd_compat.c 279 warn V1020 The function exited without calling the 'sigchld_unlock' function. Check lines: 279, 249.
/opt/pvs/accel-ppp/accel-pppd/extra/pppd_compat.c 333 warn V1020 The function exited without calling the 'sigchld_unlock' function. Check lines: 333, 315.
/opt/pvs/accel-ppp/accel-pppd/extra/pppd_compat.c 422 warn V1020 The function exited without calling the 'sigchld_unlock' function. Check lines: 422, 372.
/opt/pvs/accel-ppp/accel-pppd/extra/pppd_compat.c 488 warn V1020 The function exited without calling the 'sigchld_unlock' function. Check lines: 488, 468.
/opt/pvs/accel-ppp/accel-pppd/triton/mempool.c 119 warn V1020 The function exited without calling the 'pthread_spin_unlock' function. Check lines: 119, 116.
* Fix array len errors
/opt/pvs/accel-ppp/accel-pppd/triton/conf_file.c 75 warn V557 Array underrun is possible. The value of 'len - 1' index could reach -1.
/opt/pvs/accel-ppp/accel-pppd/triton/conf_file.c 76 warn V557 Array underrun is possible. The value of '-- len' index could reach -1.
* Fix possible memory leaks
/opt/pvs/accel-ppp/accel-pppd/radius/radius.c 936 err V773 The function was exited without releasing the 'str' pointer. A memory leak is possible.
/opt/pvs/accel-ppp/accel-pppd/radius/serv.c 622 err V773 The function was exited without releasing the 'str' pointer. A memory leak is possible.
/opt/pvs/accel-ppp/accel-pppd/triton/conf_file.c 144 err V773 The function was exited without releasing the 'raw' pointer. A memory leak is possible.
* Fix unsafe code
/opt/pvs/accel-ppp/accel-pppd/cli/tcp.c 364 warn V1004 The 'host' pointer was used unsafely after it was verified against nullptr. Check lines: 338, 364.
/opt/pvs/accel-ppp/accel-pppd/cli/telnet.c 701 warn V1004 The 'host' pointer was used unsafely after it was verified against nullptr. Check lines: 675, 701.
/opt/pvs/accel-ppp/accel-pppd/extra/ippool.c 241 err V614 Potentially uninitialized pointer 'pos' used.
/opt/pvs/accel-ppp/accel-pppd/radius/dict.c 165 err V614 Uninitialized pointer 'parent_items' used.
* Remove duplicate code
/opt/pvs/accel-ppp/accel-pppd/radius/serv.c 202 warn V547 Expression 'ts.tv_sec < req->serv->fail_time' is always false.
* Fix treating signed bool variables as unsigned
* Add nullptr checking
/opt/pvs/accel-ppp/accel-pppd/ipv6/dhcpv6.c 886 err V595 The 'opt->val' pointer was utilized before it was verified against nullptr. Check lines: 886, 890.
/opt/pvs/accel-ppp/accel-pppd/ipv6/nd.c 479 err V595 The 'opt->val' pointer was utilized before it was verified against nullptr. Check lines: 479, 483.
/opt/pvs/accel-ppp/accel-pppd/radius/auth.c 152 err V595 The 'rpd->auth_ctx' pointer was utilized before it was verified against nullptr. Check lines: 152, 154.
/opt/pvs/accel-ppp/accel-pppd/triton/conf_file.c 114 err V595 The 'cur_sect' pointer was utilized before it was verified against nullptr. Check lines: 114, 117.
* Add logging of exit conditions
* Clarify calculation
[accel-pppd/ppp/ccp_mppe.c:281]: (style) Clarify calculation precedence for '&' and '?'.
[accel-pppd/ppp/ccp_mppe.c:282]: (style) Clarify calculation precedence for '&' and '?'.
[accel-pppd/ppp/ccp_mppe.c:283]: (style) Clarify calculation precedence for '&' and '?'.
[accel-pppd/ppp/ccp_mppe.c:284]: (style) Clarify calculation precedence for '&' and '?'.
[accel-pppd/ppp/ccp_mppe.c:285]: (style) Clarify calculation precedence for '&' and '?'.
[accel-pppd/ppp/ccp_mppe.c:286]: (style) Clarify calculation precedence for '&' and '?'.
[drivers/ipoe/ipoe.c:307]: (style) Clarify calculation precedence for '&' and '?'.
* Fix void calculations
[accel-pppd/ctrl/pppoe/disc.c:211]: (portability) 'pkt' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/ctrl/pptp/pptp.c:150]: (portability) 'buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/acct.c:37]: (portability) 'req.pack.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/auth.c:35]: (portability) 'req.pack.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/auth.c:79]: (portability) 'req.pack.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/dm_coa.c:43]: (portability) 'pack.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/dm_coa.c:47]: (portability) 'pack.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/dm_coa.c:57]: (portability) 'pack.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/dm_coa.c:65]: (portability) 'req.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/dm_coa.c:97]: (portability) 'req.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/radius/serv.c:364]: (portability) 'req.pack.buf' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/triton/mempool.c:115]: (portability) 'mmap_ptr' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/triton/mempool.c:122]: (portability) 'mmap_ptr' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/triton/mempool.c:276]: (portability) 'ptr' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
* Fix void part 2
[accel-pppd/ipv6/dhcpv6.c:844]: (portability) 'conf_dnssl' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/ipv6/nd.c:199]: (portability) '(void*)dnsslinfo' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
[accel-pppd/ipv6/nd.c:432]: (portability) 'conf_dnssl' is of type 'void *'. When using void pointers in calculations, the behaviour is undefined.
* Fix null pointer dereference
[accel-pppd/ctrl/ipoe/ipoe.c:2048]: (warning) Possible null pointer dereference: eth
[accel-pppd/ctrl/ipoe/ipoe.c:2049]: (warning) Possible null pointer dereference: iph
* Remove redundant check
/opt/pvs/accel-ppp/accel-pppd/ctrl/l2tp/packet.c 656 warn V547 Expression 'attr->length <= 16' is always false.
* PR fixes
* PR fixes 2
|
|
[accel-pppd/cli/tcp.c:305]: (error) Uninitialized variable: cln
[accel-pppd/cli/telnet.c:642]: (error) Uninitialized variable: cln
[accel-pppd/ctrl/l2tp/l2tp.c:4302]: (error) Uninitialized variable: msg_attr
[accel-pppd/ctrl/l2tp/l2tp.c:4484]: (error) Uninitialized variable: msg_type
[accel-pppd/ctrl/pppoe/disc.c:169]: (error) Uninitialized variable: n
[accel-pppd/ctrl/pppoe/pppoe.c:1588]: (error) Uninitialized variable: pado
|
|
|
|
Unsufficent checks of valid l2tp header & avp length cause possible
RCE through buffer overflow, reported by https://github.com/WinMin
swings & leommxj, Chaitin Security Research Lab. Add missed header
length and avp length validation to fix the issue.
Order of struct bitfields is implementation-defined so current code
doesn't play well with big-endian arch. switch to explicit flag bit
checking/gathering to fix the issue.
RFC 2661 and 3931 requires that length, seqeuence flags must be set
and offset flag must not be set, so avp-premissive can't help in
this cases.
|
|
usually there's no need to have per-proto limitation, since the need
of max starting limitation affects the whole server, not particular
protocol only.
|
|
also, disable ipv6 pools via chap-secrets, need to find another
syntax for it, may be with comments.
|
|
original commit author is @dyangol
|
|
|
|
Reuse exsisting radius functionality and allow set iterface name
template for pppoe/pptp/l2tp, '%d' specification will be replaced
automagically to the next available index by kernel.
PPP interface rename allows to easy differ client's interfaces from
the other ppp ones, for example, with just netfilter interface rules.
Example:
[pptp]
ifname=pptp%d will produce pptp0, pptp1, ...
|
|
pptp/l2tp: echo failure improvements
|
|
With incoming l2tp hello there's no need to ask peer for
replies in configured hello-interval, so just postpone it.
Helps against false-positive echo failures with heavily
loaded channels and/or peers.
|
|
After session is freed on our end, kernel doesn't bother with possible
incoming data packets and just passes them to userspace, in turn
they are mistreated as short control packets with corresponding errors.
Since there's no special data packet handling, just ignore them.
|
|
new config option:
[common]
max-sessions=N
If set then accel-pppd stops reply to new connection requests if total number of sessions (active and starting) is reached specified limit.
|
|
This reverts commit 88a908974b0b2e9c7eee8ad9a8b0b4432e95d167.
|
|
new config option:
[common]
max-sessions=N
If set then accel-pppd stops reply to new connection requests if total number of sessions (active and starting) is reached specified limit.
|
|
This reverts commit 9ea88bac7d5bf8fc5cf2d5f7d0a734ec7a9e6df6.
|
|
new config option:
[common]
max-sessions=N
If set then accel-pppd stops reply to new connection requests if total number of sessions (active and starting) is reached specified limit.
|
|
There are three different triton contexts that use l2tp_ctx_switch() as
their ->before_switch callback (main UDP server, L2TP control and L2TP
data).
In UDP server and L2TP control contexts, l2tp_ctx_switch() is called
with 'arg' == NULL. Only L2TP data contexts pass an ap_session pointer.
So we have to check 'arg' before setting 'net' or accel-ppp would
segfaults.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
This is done using radius attribute NAS-Port-Id. The new format of this attribute is NAS-Port-Id=[ns/][name].
Namespaces must be created malually by "ip netns add ..." command
|
|
Move warning messages to PPTP and L2TP modules. No other module
actually uses iprange, so it's perfectly valid to disable it, or at
least to not configure any range, when PPTP and L2TP aren't used.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
|
|
|
|
|
|
|
|
Wait for a full retransmission cycle after reception of a StopCCN.
Introduce STATE_FIN_WAIT to identify tunnels which have received a
StopCCN but are waiting for the disconnection timer to expire.
A tunnel can go from STATE_FIN (i.e. StopCCN has been sent, waiting for
acknowledgement) to STATE_FIN_WAIT (i.e. StopCCN has been received,
waiting for full retransmission cycle), but not the other way around.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
* Set default retransmission timeout to 1 second. Since we now have
exponential backoff, we can afford a smaller value.
* Add the rtimeout-cap option to set the maximum value the
retransmission timer has to respect during exponential backoff.
* Store the maximun number of retransmissions in tunnel's structure
(like other retransmission parameters).
* Describe all these changes in man page and reset them to their
default values if they're removed from configuration file before a
reload.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Rework the l2tp_rtimeout() callback, so that time between
retransmissions expands exponentially. This allows for faster
retransmissions without without overwhelming the peer.
A cap is set on the maximum retransmission time. For now it is set to
16 seconds.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
If a peer needs to disconnect a session for which it didn't receive
any reply, it sends a CDN with no Session ID. In this case, the
Assigned Session ID AVP is the only data that can be used to find out
which session has to be closed. Though it isn't supported for now,
let's accept and ack these messages. Session will be deleted on our
side thanks to the establishment timer.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Add the recv-window option in accel-ppp.conf.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Add a fixed length receive queue to tunnels and adverdise its length to
the peer using the Receive Window Size AVP.
Incoming message handling is modified as follow:
-Read as much messages as possible and store them in the receive queue.
Messages are stored in order, based on their sequence number. Messages
not fitting into the queue are discarded (doesn't happen if peer
respects our Receive Window AVP). This is the job of the new
l2tp_tunnel_store_msg() function. It also automatically finds out if
there are new messages to acknowledge.
-Once all incoming messages have been read, free acknowledged packets
from retransmission queue (based on the highest received
acknowledgement number).
-Then process messages in the receive queue. This is done by
l2tp_tunnel_reply(). Each packet is processed by
l2tp_{tunnel,session}_recv() (or dropped in some particular cases).
The send queue is then pushed. If there's no message in the send
queue and an acknowledgement is necessary, a ZLB is sent instead.
-Finally, detect if the peer has acknowledged a StopCCN. There are
three components to this test:
-Have we tried to send a StopCCN? Check with tunnel's state.
-Has the StopCCN been pushed on the network? Check with tunnel's
send queue.
-Has the peer acknowledged the StopCCN? Check with tunnel's
retransmission queue.
For now, l2tp_tunnel_store_msg() doesn't perform fast retransmissions.
So l2tp_retransmit() is removed.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Use stacked error labels for better extensibility.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Refuse to create new sessions when the local send queue is bigger than
the peer's receive window (i.e. when there are already more outstanding
messages than what the peer can currently accept). Only sessions
initiated locally are affected, session requests from the peer are
still handled normally.
This avoids adding useless presure on the sending window when many
sessions are created locally. If sessions were created, they'd add
many ICRQ or OCRQ messages in the send queue and we'd have to wait for
all these messages to be sent before being able to reply to messages
from the peer.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Store the Receive Window Size AVP sent by peer and respect it when
sending messages. That is, stop sending messages from send queue once
the number of unacknowledged messages is higher than peer's receive
window.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Add a per session send queue. Messages sent by a session are added to
both tunnel and session queues. This allows sessions to remove their
unsent messages from tunnel's send queue before they disconnect.
The same approach is used for tunnels. Before disconnecting, they clear
their send queue to avoid sending useless messages.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|
|
Modify return value of l2tp_tunnel_push_sendqueue() to inform the
caller if a message has been sent or if the queue was empty. This
information, let l2tp_conn_read() automatically acknowledge
received messages using a ZLB when there's no response to send.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
|