GOPATH=$(GOPATH) go build -ldflags "$(LDFLAGS)" cypherpunks.ru/govpn/cmd/govpn-verifier
bench:
- GOPATH=$(GOPATH) go test -bench . cypherpunks.ru/govpn/...
+ GOPATH=$(GOPATH) go test -benchmem -bench . cypherpunks.ru/govpn/...
clean:
rm -f govpn-client govpn-server govpn-verifier
Enable @ref{Encless, encryptionless mode}.
@item -up
-Optional path to script that will be executed after connection is
-established. Interface name will be given to it as a first argument.
+Optional path to @ref{Scripts, script} that will be executed after
+connection is established. Interface name will be given to it as a first
+argument.
@item -down
Same as @option{-up} above, but it is executed when connection is lost,
@verbatim
client% cat > up.sh <<EOF
#!/bin/sh
-dhclient $1
-rtsol $1
+dhclient $GOVPN_IFACE
+rtsol $GOVPN_IFACE
EOF
client% chmod +x up.sh
@end verbatim
@multitable {XXXXX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@headitem Version @tab Size @tab Tarball @tab SHA256 checksum
+@item @ref{Release 5.6, 5.6} @tab 311 KiB
+@tab @url{download/govpn-5.6.tar.xz, link} @url{download/govpn-5.6.tar.xz.sig, sign}
+@tab @code{d46b8f742f1e2bf17236868512f1ea5ad80f59c3bac753a56ce41a1f465282a8}
+
@item @ref{Release 5.5, 5.5} @tab 310 KiB
@tab @url{download/govpn-5.5.tar.xz, link} @url{download/govpn-5.5.tar.xz.sig, sign}
@tab @code{2f32e02c34a13eae538be7b44c11e16a8e68c43afc8e4a3071172f9c52b861d8}
* Timeout::
* Time synchronization: Timesync.
* Network transport: Network.
+* Scripts::
* Proxy::
* Maximum Transmission Unit: MTU.
* Statistics: Stats.
@include timeout.texi
@include timesync.texi
@include netproto.texi
+@include scripts.texi
@include proxy.texi
@include mtu.texi
@include stats.texi
@node Новости
@section Новости
+@node Релиз 5.7
+@subsection Релиз 5.7
+@itemize
+@item Имя TAP интерфейса и адрес удалённой стороны теперь передаются в
+up- и down- скрипты через переменные окружения.
+@item Argon2 библиотека обновлена чтобы использовать 1.3 версию алгоритма.
+@end itemize
+
@node Релиз 5.6
@subsection Релиз 5.6
@itemize
See also this page @ref{Новости, on russian}.
+@node Release 5.7
+@section Release 5.7
+@itemize
+@item TAP interface name and remote peer's address are passed to up- and
+down- scripts through environment variables.
+@item Update Argon2 library to use version 1.3 of the algorithm.
+@end itemize
+
@node Release 5.6
@section Release 5.6
@itemize
--- /dev/null
+@node Scripts
+@subsection Scripts
+
+Up- and down- scripts used as a hook executed when connection is either
+established or lost. Following environment variables are set during
+their execution:
+
+@table @code
+
+@item GOVPN_REMOTE
+Remote peer's address. In client mode it is server's address.
+
+@item GOVPN_IFACE
+TAP interface name. In server mode this can be empty: that means that
+script must output its name as the first line to stdout.
+
+@end table
At least one of either @code{iface} or @code{up} must be specified. If
you specify @code{iface}, then it will be forcefully used to determine
-what TAP interface will be used. If it is not specified, then up-script
-must output interface's name to stdout (first output line).
+what TAP interface will be used. If it is not specified, then
+up-@ref{Scripts, script} must output interface's name to stdout
+(first output line).
For example up-script can be just @code{echo tap10}, or more advanced
like the following one:
-
@verbatim
#!/bin/sh
$tap=$(ifconfig tap create)
import (
"flag"
+ "fmt"
"log"
"net"
"os"
encless = flag.Bool("encless", false, "Encryptionless mode")
cpr = flag.Int("cpr", 0, "Enable constant KiB/sec out traffic rate")
egdPath = flag.String("egd", "", "Optional path to EGD socket")
+ warranty = flag.Bool("warranty", false, "Print warranty information")
conf *govpn.PeerConf
tap *govpn.TAP
func main() {
flag.Parse()
+ if *warranty {
+ fmt.Println(govpn.Warranty)
+ return
+ }
timeout = *timeoutP
var err error
log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
close(rehandshaking)
close(termination)
}
- govpn.ScriptCall(*downPath, *ifaceName)
+ govpn.ScriptCall(*downPath, *ifaceName, *remoteAddr)
}
log.Println("Handshake completed")
knownPeers = govpn.KnownPeers(map[string]**govpn.Peer{*remoteAddr: &peer})
if firstUpCall {
- go govpn.ScriptCall(*upPath, *ifaceName)
+ go govpn.ScriptCall(*upPath, *ifaceName, *remoteAddr)
firstUpCall = false
}
hs.Zero()
log.Println("Handshake completed")
knownPeers = govpn.KnownPeers(map[string]**govpn.Peer{*remoteAddr: &peer})
if firstUpCall {
- go govpn.ScriptCall(*upPath, *ifaceName)
+ go govpn.ScriptCall(*upPath, *ifaceName, *remoteAddr)
firstUpCall = false
}
hs.Zero()
heartbeat.Stop()
}
-func callUp(peerId *govpn.PeerId) (string, error) {
+func callUp(peerId *govpn.PeerId, remoteAddr string) (string, error) {
ifaceName := confs[*peerId].Iface
if confs[*peerId].Up != "" {
- result, err := govpn.ScriptCall(confs[*peerId].Up, "")
+ result, err := govpn.ScriptCall(confs[*peerId].Up, ifaceName, remoteAddr)
if err != nil {
log.Println("Script", confs[*peerId].Up, "call failed", err)
return "", err
import (
"flag"
+ "fmt"
"log"
"net"
"os"
stats = flag.String("stats", "", "Enable stats retrieving on host:port")
proxy = flag.String("proxy", "", "Enable HTTP proxy on host:port")
egdPath = flag.String("egd", "", "Optional path to EGD socket")
+ warranty = flag.Bool("warranty", false, "Print warranty information")
)
func main() {
flag.Parse()
+ if *warranty {
+ fmt.Println(govpn.Warranty)
+ return
+ }
timeout := time.Second * time.Duration(govpn.TimeoutDefault)
log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
log.Println(govpn.VersionGet())
for {
select {
case <-termSignal:
+ log.Println("Terminating")
+ for _, ps := range peers {
+ govpn.ScriptCall(
+ confs[*ps.peer.Id].Down,
+ ps.tap.Name,
+ ps.peer.Addr,
+ )
+ }
break MainCycle
case <-hsHeartbeat:
now := time.Now()
go govpn.ScriptCall(
confs[*ps.peer.Id].Down,
ps.tap.Name,
+ ps.peer.Addr,
)
ps.terminator <- struct{}{}
}
kpLock.Unlock()
log.Println("Rehandshake processed:", peer.Id.String())
} else {
- ifaceName, err := callUp(peer.Id)
+ ifaceName, err := callUp(peer.Id, peer.Addr)
if err != nil {
peer = nil
break
log.Println("Rehandshake processed:", peer.Id.String())
} else {
go func(addr string, peer *govpn.Peer) {
- ifaceName, err := callUp(peer.Id)
+ ifaceName, err := callUp(peer.Id, peer.Addr)
if err != nil {
return
}
tOpt = flag.Int("t", govpn.DefaultT, "Argon2d iteration parameter")
pOpt = flag.Int("p", govpn.DefaultP, "Argon2d parallelizm parameter")
egdPath = flag.String("egd", "", "Optional path to EGD socket")
+ warranty = flag.Bool("warranty", false, "Print warranty information")
)
func main() {
flag.Parse()
+ if *warranty {
+ fmt.Println(govpn.Warranty)
+ return
+ }
if *egdPath != "" {
govpn.EGDInit(*egdPath)
}
const (
TimeoutDefault = 60
EtherSize = 14
- MTUMax = 9000 + EtherSize
- MTUDefault = 1500 + EtherSize
+ MTUMax = 9000 + EtherSize + 1
+ MTUDefault = 1500 + EtherSize + 1
+
+ ENV_IFACE = "GOVPN_IFACE"
+ ENV_REMOTE = "GOVPN_REMOTE"
)
var (
// You have to specify path to it and (inteface name as a rule) something
// that will be the first argument when calling it. Function will return
// it's output and possible error.
-func ScriptCall(path, ifaceName string) ([]byte, error) {
+func ScriptCall(path, ifaceName, remoteAddr string) ([]byte, error) {
if path == "" {
return nil, nil
}
if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
return nil, err
}
- out, err := exec.Command(path, ifaceName).CombinedOutput()
+ cmd := exec.Command(path)
+ cmd.Env = append(cmd.Env, ENV_IFACE+"="+ifaceName)
+ cmd.Env = append(cmd.Env, ENV_REMOTE+"="+remoteAddr)
+ out, err := cmd.CombinedOutput()
if err != nil {
log.Println("Script error", path, err, string(out))
}
// Simple secure, DPI/censorship-resistant free software VPN daemon.
package govpn
+
+const (
+ Warranty = `This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.`
+)
-Subproject commit f7716cbe52baa25d2e9b0d0da546fcf909fc16b4
+Subproject commit a83829b6f1293c91addabc89d0571c246397bbf4
-Subproject commit 82d59eb7dab9a6268371a8c6de2100a2c7357bc6
+Subproject commit 190e3cf208e185668db6aa048e4985b7b7b4d890
# List of parameters passed through environment
# - reason -- why this script is called:
# pre-init, connect, disconnect
-# - VPNGATEWAY -- public address of vpn gateway
-# - TAPDEV -- tap device
+# - GOVPN_REMOTE -- public address of VPN gateway
+# - GOVPN_IFACE -- tap device
# - INTERNAL_IP4_ADDRESS -- e.g. 172.0.0.2/24
# - INTERNAL_IP4_GATEWAY -- e.g. 172.0.0.1
set_up_dev() {
- ip tuntap add dev $TAPDEV mode tap
+ ip tuntap add dev $GOVPN_IFACE mode tap
}
tear_down_dev() {
- ip tuntap del dev $TAPDEV mode tap
+ ip tuntap del dev $GOVPN_IFACE mode tap
}
do_connect() {
local OLDGW=$(ip route show 0/0 | sed 's/^default//')
- ip link set dev $TAPDEV up
- ip addr add $INTERNAL_IP4_ADDRESS dev $TAPDEV
- ip route add $VPNGATEWAY $OLDGW
- ip route add 0/1 via $INTERNAL_IP4_GATEWAY dev $TAPDEV
- ip route add 128/1 via $INTERNAL_IP4_GATEWAY dev $TAPDEV
+ ip link set dev $GOVPN_IFACE up
+ ip addr add $INTERNAL_IP4_ADDRESS dev $GOVPN_IFACE
+ ip route add $GOVPN_REMOTE $OLDGW
+ ip route add 0/1 via $INTERNAL_IP4_GATEWAY dev $GOVPN_IFACE
+ ip route add 128/1 via $INTERNAL_IP4_GATEWAY dev $GOVPN_IFACE
}
do_disconnect() {
- ip route del $VPNGATEWAY
+ ip route del $GOVPN_REMOTE
}