有没有懂 Go 和计算机网络的兄弟?

谁懂这个 demo 的含金量? /狗头 保命

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net"
	"net/http"
	"net/url"
	"os"
	"time"

	"github.com/sigcn/pg/disco"
	"github.com/sigcn/pg/langs"
	"github.com/sigcn/pg/p2p"
	"github.com/sigcn/pg/peermap/network"
	"github.com/sigcn/pg/vpn"
	"github.com/sigcn/pg/vpn/nic"
	"github.com/sigcn/pg/vpn/nic/gvisor"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
)

var (
	server     = "wss://openpg.in/pg"
	secretFile = "psns.json"
	_, ip4, _  = net.ParseCIDR("100.99.0.27/24")
)

// prepareSecret 准备 JSONSecret 用于加入 PG 网络
func prepareSecret() error {
	fetchSecret := func() error {
		join, err := network.JoinOIDC("", server)
		if err != nil {
			return err
		}
		fmt.Println("Open the following link to authenticate")
		fmt.Println(join.AuthURL())
		ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
		secret, err := join.Wait(ctx)
		cancel()
		if err != nil {
			panic(err)
		}
		f, err := os.Create(secretFile)
		if err != nil {
			return err
		}
		json.NewEncoder(f).Encode(secret)
		return nil
	}

	f, err := os.Open(secretFile)
	if err != nil {
		return fetchSecret()
	}
	var secret disco.NetworkSecret
	if err := json.NewDecoder(f).Decode(&secret); err != nil {
		return err
	}
	if time.Now().After(secret.Expire) {
		return fetchSecret()
	}
	return nil
}

// startVPN 启动 VPN (gVisor + p2p)
func startVPN(ctx context.Context) *gvisor.GvisorCard {
	s := stack.New(stack.Options{
		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
	})

	vnic := nic.VirtualNIC{NIC: &gvisor.GvisorCard{Stack: s, Config: nic.Config{IPv4: ip4.String()}}}
	packetConn := langs.Must(p2p.ListenPacket(
		&disco.Server{Secret: &disco.FileSecretStore{StoreFilePath: secretFile}, URL: server},
		p2p.ListenPeerUp(func(pi disco.PeerID, v url.Values) {
			vnic.AddPeer(nic.Peer{Addr: pi, IPv4: v.Get("alias1"), IPv6: v.Get("alias2"), Meta: v})
		}),
		p2p.ListenPeerSecure(),
		p2p.PeerAlias1(ip4.IP.String()),
	))

	go vpn.New(vpn.Config{MTU: 1371}).Run(ctx, &vnic, packetConn)
	time.Sleep(time.Second) // 等待路由表
	return vnic.NIC.(*gvisor.GvisorCard)
}

func main() {
	// 获取 JSONSecret
	if err := prepareSecret(); err != nil {
		panic(err)
	}

	// 启动 gVisor VPN
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	gvisorCard := startVPN(ctx)

	// HTTP 请求
	cli := http.Client{
		Transport: &http.Transport{DialContext: gvisorCard.DialContext},
		Timeout:   15 * time.Second,
	}

	r := langs.Must(cli.Get("http://100.99.0.2"))
	defer r.Body.Close()
	io.Copy(os.Stdout, r.Body)
}
20 Likes

DS给的评价不低哦

佬出书吧

此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。