mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 13:26:49 +08:00
尝试整个网络代理 以netstack为代理服务器,想实现网络通信的server调用特殊的api代理,要如何避开内核网络栈呢?
This commit is contained in:
215
cmd/netstack/main.go
Normal file
215
cmd/netstack/main.go
Normal file
@@ -0,0 +1,215 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"flag"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"netstack/tcpip"
|
||||
"netstack/tcpip/header"
|
||||
"netstack/tcpip/link/fdbased"
|
||||
"netstack/tcpip/link/tuntap"
|
||||
"netstack/tcpip/network/arp"
|
||||
"netstack/tcpip/network/ipv4"
|
||||
"netstack/tcpip/network/ipv6"
|
||||
"netstack/tcpip/stack"
|
||||
"netstack/tcpip/transport/udp"
|
||||
"netstack/waiter"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var mac = flag.String("mac", "01:01:01:01:01:01", "mac address to use in tap device")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if len(flag.Args()) != 2 {
|
||||
log.Fatal("Usage: ", os.Args[0], " <tap-device> <listen-address>")
|
||||
}
|
||||
|
||||
log.SetFlags(log.Lshortfile | log.LstdFlags)
|
||||
tapName := flag.Arg(0)
|
||||
listeAddr := flag.Arg(1)
|
||||
|
||||
log.Printf("tap: %v, listeAddr: %v", tapName, listeAddr)
|
||||
|
||||
// Parse the mac address.
|
||||
maddr, err := net.ParseMAC(*mac)
|
||||
if err != nil {
|
||||
log.Fatalf("Bad MAC address: %v", *mac)
|
||||
}
|
||||
|
||||
parsedAddr := net.ParseIP(listeAddr)
|
||||
|
||||
// 解析地址ip地址,ipv4或者ipv6地址都支持
|
||||
var addr tcpip.Address
|
||||
var proto tcpip.NetworkProtocolNumber
|
||||
if parsedAddr.To4() != nil {
|
||||
addr = tcpip.Address(parsedAddr.To4())
|
||||
proto = ipv4.ProtocolNumber
|
||||
} else if parsedAddr.To16() != nil {
|
||||
addr = tcpip.Address(parsedAddr.To16())
|
||||
proto = ipv6.ProtocolNumber
|
||||
} else {
|
||||
log.Fatalf("Unknown IP type: %v", parsedAddr)
|
||||
}
|
||||
|
||||
// 虚拟网卡配置
|
||||
conf := &tuntap.Config{
|
||||
Name: tapName,
|
||||
Mode: tuntap.TAP,
|
||||
}
|
||||
|
||||
var fd int
|
||||
// 新建虚拟网卡
|
||||
fd, err = tuntap.NewNetDev(conf)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 启动tap网卡
|
||||
_ = tuntap.SetLinkUp(tapName)
|
||||
// 设置tap网卡IP地址
|
||||
_ = tuntap.AddIP(tapName, listeAddr)
|
||||
|
||||
// 抽象网卡的文件接口
|
||||
linkID := fdbased.New(&fdbased.Options{
|
||||
FD: fd,
|
||||
MTU: 1500,
|
||||
Address: tcpip.LinkAddress(maddr),
|
||||
})
|
||||
|
||||
// 新建相关协议的协议栈
|
||||
s := stack.New([]string{ipv4.ProtocolName, arp.ProtocolName},
|
||||
[]string{ /*tcp.ProtocolName, */ udp.ProtocolName}, stack.Options{})
|
||||
|
||||
// 新建抽象的网卡
|
||||
if err := s.CreateNamedNIC(1, "vnic1", linkID); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 在该协议栈上添加和注册相应的网络层
|
||||
if err := s.AddAddress(1, proto, addr); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 在该协议栈上添加和注册ARP协议
|
||||
if err := s.AddAddress(1, arp.ProtocolNumber, arp.ProtocolAddress); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 添加默认路由
|
||||
s.SetRouteTable([]tcpip.Route{
|
||||
{
|
||||
Destination: tcpip.Address(strings.Repeat("\x00", len(addr))),
|
||||
Mask: tcpip.AddressMask(strings.Repeat("\x00", len(addr))),
|
||||
Gateway: "",
|
||||
NIC: 1,
|
||||
},
|
||||
})
|
||||
|
||||
conn, _ := net.Listen("tcp", "0.0.0.0:9999")
|
||||
TCPServer(conn, &RCV{s, nil, nil})
|
||||
// 同时监听tcp和udp localPort端口
|
||||
//tcpEp := tcpListen(s, proto, localPort)
|
||||
//udpEp := udpListen(s, proto, localPort)
|
||||
// 关闭监听服务,此时会释放端口
|
||||
//tcpEp.Close()
|
||||
//udpEp.Close()
|
||||
}
|
||||
|
||||
//func tcpListen(s *stack.Stack, proto tcpip.NetworkProtocolNumber, localPort int) tcpip.Endpoint {
|
||||
// var wq waiter.Queue
|
||||
// // 新建一个tcp端
|
||||
// ep, err := s.NewEndpoint(tcp.ProtocolNumber, proto, &wq)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// // 绑定IP和端口,这里的IP地址为空,表示绑定任何IP
|
||||
// // 此时就会调用端口管理器
|
||||
// if err := ep.Bind(tcpip.FullAddress{0, "", uint16(localPort)}, nil); err != nil {
|
||||
// log.Fatal("Bind failed: ", err)
|
||||
// }
|
||||
//
|
||||
// // 开始监听
|
||||
// if err := ep.Listen(10); err != nil {
|
||||
// log.Fatal("Listen failed: ", err)
|
||||
// }
|
||||
//
|
||||
// return ep
|
||||
//}
|
||||
|
||||
func udpListen(s *stack.Stack, proto tcpip.NetworkProtocolNumber, localPort int) tcpip.Endpoint {
|
||||
var wq waiter.Queue
|
||||
// 新建一个udp端
|
||||
ep, err := s.NewEndpoint(udp.ProtocolNumber, proto, &wq)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 绑定IP和端口,这里的IP地址为空,表示绑定任何IP
|
||||
// 0.0.0.0:9999 这台机器上的所有ip的9999段端口数据都会使用该传输层实现
|
||||
// 此时就会调用端口管理器
|
||||
if err := ep.Bind(tcpip.FullAddress{NIC: 0, Addr: "", Port: uint16(localPort)}, nil); err != nil {
|
||||
log.Fatal("Bind failed: ", err)
|
||||
}
|
||||
|
||||
if err := ep.Connect(tcpip.FullAddress{NIC: 0, Addr: "", Port: uint16(localPort)}); err != nil {
|
||||
log.Fatal("Conn failed: ", err)
|
||||
}
|
||||
|
||||
// 注意UDP是无连接的,它不需要Listen
|
||||
return ep
|
||||
}
|
||||
|
||||
type RCV struct {
|
||||
*stack.Stack
|
||||
ep tcpip.Endpoint
|
||||
rcvBuf []byte
|
||||
}
|
||||
|
||||
var transportPool = make(map[uint64]tcpip.Endpoint)
|
||||
|
||||
func (r *RCV) Handle(conn net.Conn) {
|
||||
var err error
|
||||
r.rcvBuf, err = io.ReadAll(conn)
|
||||
if err != nil && len(r.rcvBuf) < 9 { // proto + ip + port
|
||||
panic(err)
|
||||
}
|
||||
|
||||
switch string(r.rcvBuf[:3]) {
|
||||
case "udp":
|
||||
var wq waiter.Queue
|
||||
// 新建一个udp端
|
||||
ep, err := r.NewEndpoint(udp.ProtocolNumber, header.IPv4ProtocolNumber, &wq)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
r.ep = ep
|
||||
r.Bind()
|
||||
r.Close()
|
||||
case "tcp":
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RCV) Bind() {
|
||||
if len(r.rcvBuf) < 9 { // udp ip port
|
||||
log.Println("Error: too few arg")
|
||||
return
|
||||
}
|
||||
port := binary.BigEndian.Uint16(r.rcvBuf[7:9])
|
||||
addr := tcpip.FullAddress{
|
||||
NIC: 0,
|
||||
Addr: tcpip.Address(r.rcvBuf[3:7]),
|
||||
Port: port,
|
||||
}
|
||||
r.ep.Bind(addr, nil)
|
||||
}
|
||||
|
||||
func (r *RCV) Close() {
|
||||
r.ep.Close()
|
||||
}
|
38
cmd/netstack/tcp_server.go
Normal file
38
cmd/netstack/tcp_server.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type TCPHandler interface {
|
||||
Handle(net.Conn)
|
||||
}
|
||||
|
||||
func TCPServer(listener net.Listener, handler TCPHandler) error {
|
||||
log.Printf("netstack 网络解析地址: %s", listener.Addr())
|
||||
|
||||
for {
|
||||
clientConn, err := listener.Accept()
|
||||
if err != nil {
|
||||
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
|
||||
log.Printf("temporary Accept() failure - %s", err)
|
||||
runtime.Gosched()
|
||||
continue
|
||||
}
|
||||
// theres no direct way to detect this error because it is not exposed
|
||||
if !strings.Contains(err.Error(), "use of closed network connection") {
|
||||
return fmt.Errorf("listener.Accept() error - %s", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
go handler.Handle(clientConn)
|
||||
}
|
||||
|
||||
log.Printf("TCP: closing %s", listener.Addr())
|
||||
|
||||
return nil
|
||||
}
|
110
cmd/udp/main.go
110
cmd/udp/main.go
@@ -5,120 +5,32 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"netstack/tcpip"
|
||||
"netstack/tcpip/link/fdbased"
|
||||
"netstack/tcpip/link/tuntap"
|
||||
"netstack/tcpip/network/arp"
|
||||
"netstack/tcpip/network/ipv4"
|
||||
"netstack/tcpip/network/ipv6"
|
||||
"netstack/tcpip/stack"
|
||||
"netstack/tcpip/transport/udp"
|
||||
"netstack/waiter"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var mac = flag.String("mac", "01:01:01:01:01:01", "mac address to use in tap device")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if len(flag.Args()) != 3 {
|
||||
log.Fatal("Usage: ", os.Args[0], " <tap-device> <listen-address> port")
|
||||
if len(flag.Args()) != 2 {
|
||||
log.Fatal("Usage: ", os.Args[0], "<listen-address> port")
|
||||
}
|
||||
|
||||
log.SetFlags(log.Lshortfile | log.LstdFlags)
|
||||
tapName := flag.Arg(0)
|
||||
listeAddr := flag.Arg(1)
|
||||
portName := flag.Arg(2)
|
||||
listeAddr := flag.Arg(0)
|
||||
portName := flag.Arg(1)
|
||||
|
||||
log.Printf("tap: %v, listeAddr: %v, portName: %v", tapName, listeAddr, portName)
|
||||
Socket(listeAddr + ":" + portName)
|
||||
}
|
||||
|
||||
// Parse the mac address.
|
||||
maddr, err := net.ParseMAC(*mac)
|
||||
func Socket(addr string) {
|
||||
conn, err := net.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
log.Fatalf("Bad MAC address: %v", *mac)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
parsedAddr := net.ParseIP(listeAddr)
|
||||
|
||||
// 解析地址ip地址,ipv4或者ipv6地址都支持
|
||||
var addr tcpip.Address
|
||||
var proto tcpip.NetworkProtocolNumber
|
||||
if parsedAddr.To4() != nil {
|
||||
addr = tcpip.Address(parsedAddr.To4())
|
||||
proto = ipv4.ProtocolNumber
|
||||
} else if parsedAddr.To16() != nil {
|
||||
addr = tcpip.Address(parsedAddr.To16())
|
||||
proto = ipv6.ProtocolNumber
|
||||
} else {
|
||||
log.Fatalf("Unknown IP type: %v", parsedAddr)
|
||||
}
|
||||
|
||||
localPort, err := strconv.Atoi(portName)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to convert port %v: %v", portName, err)
|
||||
}
|
||||
|
||||
// 虚拟网卡配置
|
||||
conf := &tuntap.Config{
|
||||
Name: tapName,
|
||||
Mode: tuntap.TAP,
|
||||
}
|
||||
|
||||
var fd int
|
||||
// 新建虚拟网卡
|
||||
fd, err = tuntap.NewNetDev(conf)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 启动tap网卡
|
||||
_ = tuntap.SetLinkUp(tapName)
|
||||
// 设置tap网卡IP地址
|
||||
_ = tuntap.AddIP(tapName, listeAddr)
|
||||
|
||||
// 抽象网卡的文件接口
|
||||
linkID := fdbased.New(&fdbased.Options{
|
||||
FD: fd,
|
||||
MTU: 1500,
|
||||
Address: tcpip.LinkAddress(maddr),
|
||||
})
|
||||
|
||||
// 新建相关协议的协议栈
|
||||
s := stack.New([]string{ipv4.ProtocolName, arp.ProtocolName},
|
||||
[]string{ /*tcp.ProtocolName, */ udp.ProtocolName}, stack.Options{})
|
||||
|
||||
// 新建抽象的网卡
|
||||
if err := s.CreateNamedNIC(1, "vnic1", linkID); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 在该协议栈上添加和注册相应的网络层
|
||||
if err := s.AddAddress(1, proto, addr); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 在该协议栈上添加和注册ARP协议
|
||||
if err := s.AddAddress(1, arp.ProtocolNumber, arp.ProtocolAddress); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 添加默认路由
|
||||
s.SetRouteTable([]tcpip.Route{
|
||||
{
|
||||
Destination: tcpip.Address(strings.Repeat("\x00", len(addr))),
|
||||
Mask: tcpip.AddressMask(strings.Repeat("\x00", len(addr))),
|
||||
Gateway: "",
|
||||
NIC: 1,
|
||||
},
|
||||
})
|
||||
|
||||
// 同时监听tcp和udp localPort端口
|
||||
//tcpEp := tcpListen(s, proto, localPort)
|
||||
udpEp := udpListen(s, proto, localPort)
|
||||
// 关闭监听服务,此时会释放端口
|
||||
//tcpEp.Close()
|
||||
udpEp.Close()
|
||||
conn.Write([]byte("udp\xc0\xa8\x01\x01\x27\x0f")) // bind udp 192.168.1.1 9999
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
//func tcpListen(s *stack.Stack, proto tcpip.NetworkProtocolNumber, localPort int) tcpip.Endpoint {
|
||||
|
@@ -76,6 +76,7 @@ type Options struct {
|
||||
Stats tcpip.Stats
|
||||
}
|
||||
|
||||
// New 新建一个网络协议栈
|
||||
func New(network []string, transport []string, opts Options) *Stack {
|
||||
clock := opts.Clock
|
||||
if clock == nil {
|
||||
@@ -115,7 +116,9 @@ func New(network []string, transport []string, opts Options) *Stack {
|
||||
proto: transProto,
|
||||
}
|
||||
}
|
||||
// TODO 添加传输层分流器
|
||||
// 添加传输层分流器
|
||||
s.demux = newTransportDemuxer(s)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
|
@@ -21,3 +21,8 @@ type transportEndpoints struct {
|
||||
type transportDemuxer struct {
|
||||
protocol map[protocolIDs]*transportEndpoints
|
||||
}
|
||||
|
||||
// 新建一个分流器
|
||||
func newTransportDemuxer(stacl *Stack) *transportDemuxer {
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user