예제 #1
0
func ServerStart(bindAddr, proto, confPath, stats, proxy, egdPath string, mtu int) {
	timeout := time.Second * time.Duration(govpn.TimeoutDefault)
	log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
	log.Println(govpn.VersionGet())

	if len(bindAddr) <= 0 {
		bindAddr = "[::]:1194"
	}
	if len(proto) <= 0 {
		proto = "udp"
	}
	if len(confPath) <= 0 {
		confPath = "peers.json"
	}
	if mtu <= 0 {
		mtu = 1452
	}

	govpn.MTU = mtu
	confInit(&confPath)
	knownPeers = govpn.KnownPeers(make(map[string]**govpn.Peer))

	if egdPath != "" {
		log.Println("Using", egdPath, "EGD")
		govpn.EGDInit(egdPath)
	}

	switch proto {
	case "udp":
		startUDP(&bindAddr)
	case "tcp":
		startTCP(&bindAddr)
	case "all":
		startUDP(&bindAddr)
		startTCP(&bindAddr)
	default:
		log.Fatalln("Unknown protocol specified")
	}

	termSignal := make(chan os.Signal, 1)
	signal.Notify(termSignal, os.Interrupt, os.Kill)

	hsHeartbeat := time.Tick(timeout)
	go func() { <-hsHeartbeat }()

	log.Println("Max MTU on TAP interface:", govpn.TAPMaxMTU())
	if stats != "" {
		log.Println("Stats are going to listen on", stats)
		statsPort, err := net.Listen("tcp", stats)
		if err != nil {
			log.Fatalln("Can not listen on stats port:", err)
		}
		go govpn.StatsProcessor(statsPort, &knownPeers)
	}
	if proxy != "" {
		go proxyStart(&proxy)
	}
	log.Println("Server started")

	var needsDeletion bool
MainCycle:
	for {
		select {
		case <-termSignal:
			break MainCycle

		case <-hsHeartbeat:
			now := time.Now()
			hsLock.Lock()
			for addr, hs := range handshakes {
				if hs.LastPing.Add(timeout).Before(now) {
					log.Println("Deleting handshake state", addr)
					hs.Zero()
					delete(handshakes, addr)
				}
			}
			peersLock.Lock()
			peersByIdLock.Lock()
			kpLock.Lock()
			for addr, ps := range peers {
				ps.peer.BusyR.Lock()
				needsDeletion = ps.peer.LastPing.Add(timeout).Before(now)
				ps.peer.BusyR.Unlock()
				if needsDeletion {
					log.Println("Deleting peer", ps.peer)
					delete(peers, addr)
					delete(knownPeers, addr)
					delete(peersById, *ps.peer.Id)
					go govpn.ScriptCall(
						confs[*ps.peer.Id].Down,
						ps.tap.Name,
					)
					ps.terminator <- struct{}{}
				}
			}
			hsLock.Unlock()
			peersLock.Unlock()
			peersByIdLock.Unlock()
			kpLock.Unlock()
		}
	}
}
예제 #2
0
func main() {
	flag.Parse()
	timeout = *timeoutP
	var err error
	log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)

	govpn.MTU = *mtu

	if *egdPath != "" {
		log.Println("Using", *egdPath, "EGD")
		govpn.EGDInit(*egdPath)
	}

	verifier, err := govpn.VerifierFromString(*verifierRaw)
	if err != nil {
		log.Fatalln(err)
	}
	priv := verifier.PasswordApply(govpn.StringFromFile(*keyPath))
	conf = &govpn.PeerConf{
		Id:       verifier.Id,
		Timeout:  time.Second * time.Duration(timeout),
		Noise:    *noisy,
		CPR:      *cpr,
		Verifier: verifier,
		DSAPriv:  priv,
	}
	idsCache = govpn.NewCipherCache([]govpn.PeerId{*verifier.Id})
	log.Println(govpn.VersionGet())

	tap, err = govpn.TAPListen(*ifaceName)
	if err != nil {
		log.Fatalln("Can not listen on TAP interface:", err)
	}

	log.Println("Max MTU on TAP interface:", govpn.TAPMaxMTU())
	if *stats != "" {
		log.Println("Stats are going to listen on", *stats)
		statsPort, err := net.Listen("tcp", *stats)
		if err != nil {
			log.Fatalln("Can not listen on stats port:", err)
		}
		go govpn.StatsProcessor(statsPort, &knownPeers)
	}

	termSignal := make(chan os.Signal, 1)
	signal.Notify(termSignal, os.Interrupt, os.Kill)

MainCycle:
	for {
		timeouted := make(chan struct{})
		rehandshaking := make(chan struct{})
		termination := make(chan struct{})
		if *proxyAddr != "" {
			*proto = "tcp"
		}
		switch *proto {
		case "udp":
			go startUDP(timeouted, rehandshaking, termination)
		case "tcp":
			if *proxyAddr != "" {
				go proxyTCP(timeouted, rehandshaking, termination)
			} else {
				go startTCP(timeouted, rehandshaking, termination)
			}
		default:
			log.Fatalln("Unknown protocol specified")
		}
		select {
		case <-termSignal:
			log.Fatalln("Finishing")
			termination <- struct{}{}
			break MainCycle
		case <-timeouted:
			break MainCycle
		case <-rehandshaking:
		}
		close(timeouted)
		close(rehandshaking)
		close(termination)
	}
	govpn.ScriptCall(*downPath, *ifaceName)
}