add initial Peer-to-peer VPN support

This commit is contained in:
ohrensessel 2015-05-17 15:20:29 +02:00
parent 80906c2a0c
commit 94db750284
5 changed files with 231 additions and 0 deletions

View File

@ -0,0 +1,40 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-p2p-vpn-fastd
PKG_VERSION:=3
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
define Package/gluon-p2p-vpn-fastd
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Support for connecting batman-adv meshes via p2p fastd
DEPENDS:=+gluon-core +gluon-mesh-vpn-fastd
endef
define Package/gluon-p2p-vpn-fastd/description
Gluon community wifi mesh firmware framework: fastd support for p2p connections
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/gluon-p2p-vpn-fastd/install
$(CP) ./files/* $(1)/
endef
define Package/gluon-p2p-vpn-fastd/postinst
#!/bin/sh
$(call GluonCheckSite,check_site.lua)
endef
$(eval $(call BuildPackage,gluon-p2p-vpn-fastd))

View File

@ -0,0 +1,26 @@
need_string_array('fastd_mesh_vpn.methods')
need_number('fastd_mesh_vpn.mtu')
need_boolean('fastd_mesh_vpn.enabled', false)
need_boolean('fastd_mesh_vpn.configurable', false)
local function check_peer(prefix)
return function(k, _)
local table = string.format('%s[%q].', prefix, k)
need_string(table .. 'key')
need_string_array(table .. 'remotes')
end
end
local function check_group(prefix)
return function(k, _)
local table = string.format('%s[%q].', prefix, k)
need_number(table .. 'limit', false)
need_table(table .. 'peers', check_peer(table .. 'peers'), false)
need_table(table .. 'groups', check_group(table .. 'groups'), false)
end
end
need_table('fastd_mesh_vpn.groups', check_group('fastd_mesh_vpn.groups'))

View File

@ -0,0 +1,18 @@
#!/usr/bin/lua
local uci = require('luci.model.uci').cursor()
local e = uci:get('fastd', 'mesh_vpn', 'enabled')
if not e then
e = '0'
end
uci:section('fastd', 'peer_group', 'p2p_vpn',
{
enabled = e,
net = 'mesh_vpn',
}
)
uci:save('fastd')
uci:commit('fastd')

View File

@ -0,0 +1,19 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.admin.p2pvpn", package.seeall)
function index()
entry({"admin", "p2pvpn"}, cbi("admin/p2pvpn"), _("P2P VPN"), 80)
end

View File

@ -0,0 +1,128 @@
local f, s, o
local uci = luci.model.uci.cursor()
local config = 'fastd'
local groupname = 'p2p_vpn'
local vpnname = 'mesh_vpn'
function splitRemoteEntry(p)
local host, port, x
p = p:gsub("["..'"'.."]", '')
x = p:find(" ") or (#p + 1)
host = p:sub(1, x-1)
p = p:sub(x+1)
x = p:find(" ") or (#p + 1)
port = p:sub(x+1)
return host, port
end
function splitPeerString(p)
local host, port, key, x
x = p:find(':') or (#p + 1)
host = p:sub(1,x-1)
p = p:sub(x+1)
x = p:find('/') or (#p + 1)
port = p:sub(1,x-1)
key = p:sub(x+1)
return host, port, key
end
function getPeerStrings()
peers = {}
uci:foreach('fastd', 'peer',
function(s)
if s['group'] == groupname then
local host, port = splitRemoteEntry(table.concat(s['remote']))
peers[#peers+1] = host .. ':' .. port .. '/' .. s['key']
end
end
)
return peers
end
f = SimpleForm(groupname, translate("Peer-to-peer Mesh VPN"))
f.template = "admin/expertmode"
s = f:section(SimpleSection, nil, translate(
'Your node can additionally connect to other nodes in a Peer-to-peer fashion.'
))
o = s:option(Flag, "enabled", translate("Enabled"))
o.default = uci:get_bool(config, groupname, "enabled") and o.enabled or o.disabled
o.rmempty = false
o = s:option(DynamicList, "hostname", translate("Remote"), translate("Format") ..": HOSTNAME:PORT/KEY")
o:write(nil, getPeerStrings())
o:depends("enabled", '1')
s = f:section(SimpleSection, nil, translate(
'One of the participating nodes of a P2P connection has to be configured with a fixed fastd port.'
..'This port then has to be forwarded in the local home router which the node is using for Mesh VPN.'
))
o:depends("enabled", '1')
o = s:option(Flag, "fixedport", translate("Fixed VPN Port"))
o.default = (uci:get(config, vpnname, "bind")) and o.enabled or o.disabled
o.rmempty = false
p = uci:get(config, vpnname, "bind")
x = p:find(":") or (#p + 1)
o = s:option(Value, "localport", translate("Port"))
o:write('', p:sub(x+1))
o:depends("fixedport", '1')
function f.handle(self, state, data)
if state == FORM_VALID then
-- delete all existin p2p peers
uci:foreach('fastd', 'peer',
function(s)
if s['group'] == groupname then
uci:delete(config, s['.name'])
end
end
)
-- iterate over dynamic list if enabled
if data.enabled == '1' and #data.hostname > 0 then
for v,peer in pairs(data.hostname) do
-- TODO: add sanity checks
local host, port, key = splitPeerString(peer)
-- hostname is cleaned to be valid as a section name
uci:section(config, 'peer', groupname .. '_' .. host:gsub('%W',''),
{
net = vpnname,
key = key,
group = groupname,
remote = { '"'..host..'"'..' port '..port },
enabled = 1,
}
)
end
end
if data.fixedport == '1' and #data.localport > 0 then
-- TODO: add sanity checks
uci:set(config, vpnname, 'bind', 'any:'..data.localport)
else
uci:delete(config, vpnname, 'bind')
end
uci:save("fastd")
uci:commit("fastd")
end
end
return f