summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/l2tp/l2tp.c
AgeCommit message (Collapse)Author
2013-02-13l2tp: Fix challenge response with no secretGuillaume Nault
Don't call strlen() if conf_secret is NULL. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Add support for placing incomming callsGuillaume Nault
Implement incomming call placement for tunnels operating as LAC. A user can place incomming calls using the command line interface. For example, the following command will place a call on tunnel 1: accel-ppp# l2tp create session tid 1 Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Implement on demand tunnel creationGuillaume Nault
Add the "l2tp create tunnel" command to initiate new tunnels. This command accepts three parameters: * peer-addr (mandatory): IPv4 address of the remote tunnel end. * host-addr (optional): IPv4 address of the local tunnel end. By default the "l2tp bind" configuration option is used (if defined). * mode (optional): tunnel operating mode: lac (default) or lns. Example with the telnet interface: accel-ppp# l2tp create tunnel peer-addr 192.0.2.1 host-addr 192.0.2.2 The above command tells accel-ppp to establish a new tunnel with the peer at 192.0.2.1. The local address will be 192.0.2.2 and the tunnel will operate as lac. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Connect to peer once first reply receivedGuillaume Nault
When peer's port isn't known (i.e. right after a tunnel establishment request has been sent), use the source port of the first peer's response as the destination port of any future L2TP message sent over that tunnel. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Replace the lns_addr tunnel field by host_addrGuillaume Nault
Rename field lns_addr, as it identifies the host address, whether it be a LAC or a LNS. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Replace the lac_addr tunnel field by peer_addrGuillaume Nault
Rename field lac_addr, as it identifies the peer address, whether it be a LAC or a LNS. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Add l2tp mode flag (LAC or LNS)Guillaume Nault
Define the lns_mode flag for tunnels and sessions to keep track of their operating state. A session's mode is inherited from its parent tunnel. The session's mode is used to set the PPPOL2TP_SO_LNSMODE socket option to its PPP socket. For tunnels, the mode is used to define how new sessions may be created: -In LNS mode, new sessions may be created by accepting incomming calls (ICRQ) or by placing outgoing calls (OCRQ). -In LAC mode, tunnels will create sessions by accepting outgoing calls or by placing incomming calls. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Add WAIT_SCCRP stateGuillaume Nault
Define STATE_WAIT_SCCRP which will be required for creating new tunnels on behalf of the host. This state will be entered right after sending an SCCRQ message. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Update Ns/Nr handlingGuillaume Nault
Change the meaning of the Nr field in struct l2tp_conn_t: instead of setting it to the last received message sequence, set it with the value of the next expected message sequence number (i.e. one above the previous value). This simplifies processing and avoids the l2tp_send() function to increment the L2TP packet Nr field (it's now directly set to the correct value). Having Nr correctly set before calling l2tp_send() is necessary for implementing tunnel establishment requests (SCCRQ messages) since the Nr field of this message must be 0. This patch also replaces the formula used to check if a message Ns is lower than a tunnel Nr. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Set LNS address with the one really bound toGuillaume Nault
When allocating tunnels, set the lns_addr field of tunnels using getsockname() instead of using the "host" parameter. This will allow the caller to pass an unspecified port in "host" (for binding to any source port) and to set the lns_addr field with the address really bound to. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Remove unused parameter in tunnel allocationGuillaume Nault
Remove the "serv" parameter from l2tp_tunnel_alloc() prototype. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Implement peer authenticationGuillaume Nault
Send the Challenge AVP in SCCRP messages and check for the Challenge Response AVP in SCCCN. This patch adds two functions: -l2tp_tunnel_genchall() generates the Challenge, stores it in the tunnel structure and adds the AVP in the packet to be sent. -l2tp_tunnel_checkchallresp() reads a Challenge Response, computes the expected response using the Challenge stored in the tunnel structure and finally checks if both responses match. These two functions are meant to be used in the upcoming implementation of SCCRQ message sending and SCCRP message reception. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Define function to compute Challenge ResponseGuillaume Nault
Create the l2tp_tunnel_genchallresp() function for building and adding the Challenge Response AVP to messages that need it. Support for this AVP is needed for sending SCCRP and SCCCN messages. This patch replaces the previous Challenge Response computation by calling the new function and prepares implementation of SCCCN message sending. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Use separate function for computing CHAP-MD5Guillaume Nault
Move challenge computation out of tunnel allocation by using a generic CHAP-MD5 calculation function. This will allow to initiate tunnels on the host side (i.e. sending SCCRQ) and to compute the challenge response later on, when handling the peer response (i.e. during SCCRP handling). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Pass peer address as sockaddr in tunnel alloc.Guillaume Nault
Use a "struct sockaddr_in" pointer for passing the peer address to the tunnel allocation function (instead of a "struct l2tp_packet_t *"). This makes l2tp_tunnel_alloc() usable in situations where tunnel creation doesn't happen in response to a peer request. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Display SCCRQ packets in l2tp_recv_SCCRQ()Guillaume Nault
The "recv <SCCRQ packet>" message printing should logically belong to the SCCRQ message reception function. This patch moves this message from l2tp_tunnel_alloc() to l2tp_recv_SCCRQ() in order to make l2tp_tunnel_alloc() usable in situations different than SCCRQ message handling. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Pass host address as sockaddr in tunnel alloc.Guillaume Nault
Pass the host address as a directly usable sockaddr_in in l2tp_tunnel_alloc(), instead of an in_pktinfo. This will allow to allocate tunnels without having to artificially create in_pktinfo structures in situations where the tunnel is not created in response to an SCCRQ. As a side effect, this patch makes accel-ppp reply to SCCRQ using an arbitrary source port, as specified in RFC 2661. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Alloc tunnels with integer framing cap.Guillaume Nault
Directly pass the framing capabilities argument of l2tp_tunnel_alloc() as an integer. The previous type (struct l2tp_attr_t *) won't make make sense when creating a tunnel in situations different from SCCRQ message handling. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: No peer-tid assignment in tunnel allocationGuillaume Nault
Peer TID assignment is specific to SCCRQ message processing. When creating a tunnel in different conditions (e.g. upon user request), the peer TID will be unknown. This patch moves peer TID assignment from l2tp_tunnel_alloc() to l2tp_recv_SCCRQ(). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Separate tunnel launching from initialisationGuillaume Nault
Register and start triton contexts/handlers in l2tp_tunnel_start() instead of l2tp_tunnel_alloc(). The objective is to make l2tp_tunnel_alloc() more generic by removing some specific initialisation code. At a later stage, these would be done by the caller between the calls to l2tp_tunnel_alloc() and l2tp_tunnel_start(). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Support for freeing partially initialised tunnelsGuillaume Nault
Avoid unregistering uninitialised tunnel data when freeing tunnel structures. This makes l2tp_tunnel_free() suitable for freeing partially initialised tunnels. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Make l2tp_tunnel_alloc() return a new tunnelGuillaume Nault
Update the prototype of l2tp_tunnel_alloc() so that it returns the allocated tunnel structure. This will allow the caller to act on the newly created tunnel in different ways depending on the creation context. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Add error checking for l2tp_tunnel_alloc()Guillaume Nault
Verify return values of functions called by l2tp_tunnel_alloc(). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-12l2tp: Send EV_CTRL_FINISHED only on established sessionsGuillaume Nault
Don't send the EV_CTRL_FINISHED event when closing sessions which haven't been established, because no corresponding EV_CTRL_STARTED events have been sent by such sessions. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-06l2tp: Remove unused field "state2" in struct l2tp_sess_tGuillaume Nault
Since it's not possible to mix incomming and outgoing states in a session, the "state2" field isn't necessary. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-06l2tp: Implement outgoing callsGuillaume Nault
Add the "l2tp create session" command to place an outgoing call. For example, "l2tp create session tid 3" will send an OCRQ within tunnel 3. This allows the LNS to request establishment of a new session inside an existing tunnel. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-02-06l2tp: No automatic CDN before cancelling sessionsGuillaume Nault
This patch removes the automatic sending of a CDN message when cancelling creation of new sessions. This is necessary in order to give the possibility for a tunnel to create (and possibly cancel) new sessions on its own (e.g. for placing outgoing calls). In such cases, sending a CDN message would not make sense if the session gets cancelled before any creation message was sent. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25Fix boolean options parsing in configuration fileGuillaume Nault
Explicitely interpret zero values when parsing boolean options. This allows to unset boolean parameters such as "verbose" when reloading the configuration. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Fix the connect() call when allocating tunnelsGuillaume Nault
Retrieve the socket address size from the address passed to connect(). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Close tunnel handler's FD if TID assignment failsGuillaume Nault
Use l2tp_tunnel_alloc() cleanup code for handling TID assignment failure. The previous manual cleanup did not close the triton handler file descriptor. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Always acknowledge SCCCN messagesGuillaume Nault
Tunnel establishment may not be immediately followed by the creation of a new session. In this case there is no message to send to the peer after receiving an SCCCN; so it won't be acknowledged and the peer will then have to retransmit it. This patch makes the tunnel always acknowledge SCCCN by replying with a ZLB, thus avoiding useless retransmission from the peer. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Acknowledge CDN messagesGuillaume Nault
Send a ZLB upon reception of a CDN message. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Avoid sending CDN with reserved result valueGuillaume Nault
Update call to l2tp_send_CDN() to avoid using the 0 result code (reserved by RFC 2661). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Register sessions timers in sessions contextGuillaume Nault
The sessions timeout timers were registered in the triton context of their parent tunnel. This patch uses the session's context instead because the timer's callback function, l2tp_session_timeout(), expects to be called from a session context. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Fix PPP session disconnectionGuillaume Nault
When a PPP session terminates on its own (i.e. not on behalf of a L2TP tunnel/session request), the l2tp_ppp_finished() callback calls the L2TP session disconnection function without updating the session's state. Session disconnection code then works like if the PPP session was still up: it tries to disconnect the PPP by calling ap_session_terminate(). But since the PPP is already terminated, it returns immediately, without calling the l2tp_ppp_finished() callback; so session cleanup won't happen. This patch updates the session's state upon PPP disconnection, so that the session disconnection code won't try to disconnect the PPP in __l2tp_session_free(). The stat_active counter is now updated inside the l2tp_ppp_finished() callback so that it gets called upon any PPP disconnection. Sending of the EV_CTRL_FINISHED event has also been moved. It is now performed in the generic part of __l2tp_session_free() because it has to be done every time the session really terminates. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Perform session disconnection in ppp contextGuillaume Nault
PPP and L2TP session contexts are the same. So since l2tp_ppp_finished() is called within the PPP context, it doesn't need to switch to the session context for calling l2tp_ppp_session_disconnect(). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Fix race condition when removing sessionsGuillaume Nault
Freeing a session requires four steps: 1-The session asynchronously requests its parent tunnel to remove the session (the tunnel must start the process). 2-The parent tunnel removes its reference to this session, then makes an asynchronous call to the session cleanup function. 3-The session performs its cleanup, frees its memory and asynchronously notifies its parent tunnel. 4-The parent tunnel decrements its sessions counter (so that it knows when it doesn't have any session depending on it). If two requests, A and B, for removing the same session, arrive almost simultaneously, then the following scenario may occur: 1a-The session handles request A and transmits it to its parent tunnel. 2a-The parent tunnel removes its reference to this session and requests the session to perform cleanup. 1b-In the mean time, the session handles request B and transmit it to its parent tunnel. 3a-The session continues to handle request A, cleans up the session and frees memory. 2b-The parent tunnel handles request B: it removes its reference to the session and tells it to perform cleanup. But the session pointer used has just been freed at step 3a. This patch modifies step 1, so that the session transmit the session-id instead of a pointer to the session structure. That way, the tunnel can check if the session has already been deleted (or is pending deletion), without having to manipulate a potentially invalid pointer. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-25l2tp: Ensure sessions always have a valid parent tunnelGuillaume Nault
Use a session counter for each tunnel to avoid freeing a tunnel while still having sessions depending on it. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2013-01-24merge upstreamKozlov Dmitry
2012-09-09l2tp: send CDN in tunnel contextKozlov Dmitry
2012-09-09l2tp: prefix connection logs with lac ip:portKozlov Dmitry
2012-09-07L2TP: Re-enable per session logsGuillaume Nault
Use a triton context per session so that log_ppp_*() functions can prepend log messages with PPP session information. Since functions must now be called within the right context, allocating and freeing sessions is done in the following manner: * Tunnels allocate new sessions within their own context and activate the new session's context just before answering the ICRQ. * Freeing sessions is slightly more complex. The session is first removed from its tunnel session list (done within the tunnel context), then the session itself if disconnected and freed (done within the session context). The l2tp_tunnel_*() and the l2tp_session_*() functions must now be used within tunnel and session contexts respectively. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Handle multiple sessions per tunnelGuillaume Nault
Accept to create several sessions for each tunnel. Session IDs are generated randomly and stored in a binary search tree in their corresponding tunnel (i.e. field "sessions" of the l2tp_conn_t structure). A new mempool is defined for session allocations. Generation of the session IDs is simple but quite limited: it selects a 16 bits random ID and checks if a session with this ID already exists. If so the allocation fails and the session is closed. Otherwise the selected ID is used for the new session. So tunnels that handle many sessions may reject new ones, even if unused session IDs are available (just because the randomly choosen ID is already in use). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Use different connection timers for tunnels and sessionsGuillaume Nault
Deactivate the tunnel connection establishment timer upon reception of SCCCN messages and use a new session specific timer for session establishment. This new session timer follows the same behaviour as the tunnel timeout timer: it is activated when sending the ICRP message and deactivated upon reception of the corresponding ICCN message. This approach is necessary for handling several sessions per tunnel, but it generates the following side effect: if a tunnel is created but no session establishment is requested from the LAC, the tunnel will no longer be automatically torn down (since the tunnel is correctly set up, its timer is no longer running, but since no session establishment process has been started, there is no session timer neither). Later on, tunnel and session timers could be turned into inactivity timeouts to address this limitation. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Allocate new sessions after receiving ICRQ messagesGuillaume Nault
Separate tunnels and sessions allocation: initialise tunnels after receiving SCCRQ messages (with no session inside), then initialise sessions upon reception of ICRQ messages. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Modify prototype of functions acting only on sessionsGuillaume Nault
Pass a struct l2tp_sess_t as parameter of functions acting on sessions, instead of retrieving the session from an l2tp_conn_t structure (which will no longer be possible once tunnels will handle several sessions). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Close only session (not tunnel) after a PPP disconnectionGuillaume Nault
When a PPP connection is torn down, close the underlying session but not the tunnel (unless its last session has been closed). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Start sending HELLO messages upon tunnel connectionGuillaume Nault
Make HELLO messages independent from PPP connections (HELLO messages are tunnel specific). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Add standalone StopCCN message sending functionGuillaume Nault
Split StopCCN message building/sending from l2tp_terminate to make it re-usable. Rename l2tp_terminate() to l2tp_tunnel_disconnect() for consistency with other tunnel/session management functions. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
2012-09-07L2TP: Terminate sessions without closing tunnelGuillaume Nault
Implement CDN message sending in order to give the possibility to close a session without closing the underlying tunnel (close a tunnel only when closing its last session, which is always the case as long as session-multiplexing is not implemented). Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>