Networking 如何在L3网络层上侦听?

Networking 如何在L3网络层上侦听?,networking,go,ip,load-balancing,packet,Networking,Go,Ip,Load Balancing,Packet,我正在创建一个聊天应用程序后端,并希望考虑可伸缩性 我想创建一个负载平衡器,但不是在HTTP所在的L7层上,而是在IP网络所在的L3层上,以直接连接到特定的服务器,然后在那里我可以进行TCP 用于侦听IP层上的数据包的函数是否正确 例如,它与较高的相同吗?这是实现负载平衡器所需的正确方法吗 是否有关于数据包结构的参考,以便我能够从中获得源IP和目标IP转发它们 如果没有,请告诉我在L3网络层上使用哪个函数侦听以平衡到其他服务器的负载。是之后,此函数将帮助您接收IP数据包 ListenIP的作用类

我正在创建一个聊天应用程序后端,并希望考虑可伸缩性

我想创建一个负载平衡器,但不是在HTTP所在的L7层上,而是在IP网络所在的L3层上,以直接连接到特定的服务器,然后在那里我可以进行
TCP

用于侦听IP层上的数据包的函数是否正确

例如,它与较高的相同吗?这是实现负载平衡器所需的正确方法吗

是否有关于数据包结构的参考,以便我能够从中获得源IP和目标IP转发它们

如果没有,请告诉我在L3网络层上使用哪个函数侦听以平衡到其他服务器的负载。

是之后,此函数将帮助您接收IP数据包

ListenIP的作用类似于IP网络的ListenPacket

类似于但适用于IP数据包

至于IP包的结构,以及如何使用它们,
net
包似乎没有这样的功能

还有另一个包,它看起来可以帮助您读取和修改来自任何层的数据包

gopacket
中有一个类型,允许使用网络层

Packet.NetworkLayer()


注意:现在我已经写了这整件事,我不得不想象有人已经写了一个很好的覆盖层/包装器来简化这件事。这只是我用谷歌搜索10分钟的结果。也许其他人会用更好的工具/方法回答,是的,此功能将帮助您接收IP数据包

ListenIP的作用类似于IP网络的ListenPacket

类似于但适用于IP数据包

至于IP包的结构,以及如何使用它们,
net
包似乎没有这样的功能

还有另一个包,它看起来可以帮助您读取和修改来自任何层的数据包

gopacket
中有一个类型,允许使用网络层

Packet.NetworkLayer()


注意:现在我已经写了这整件事,我不得不想象有人已经写了一个很好的覆盖层/包装器来简化这件事。这只是我用谷歌搜索10分钟的结果。也许其他人会用更好的工具/方法回答我个人的问题,我用它来捕获多个网络层,这个库给人留下了深刻的印象

使用gopacket时,可以通过指定多个网络层来捕获它们,例如
Ipv4
TCP
以太网
。。。 有关详细信息,请参阅

然后,您可以使用组成整个数据包的一组字节
packet.Data()
来分析层,然后打开数据包类型以执行一些操作

例如,在
eth0
上捕获多个网络层:

package main

import (
    "fmt"
    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
    "time"
)

//Layers we want to decode
var (
    ip4 layers.IPv4
    eth layers.Ethernet
    tcp layers.TCP
)

func main() {

    //Array to store decoded layers
    decodedLayers := []gopacket.LayerType{}

    //Create parser
    parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &tcp)

    //Here we use pcap to capture packet on eth0 interface, we can also use afpacket for example, which is more efficient
    handle, err := pcap.OpenLive("eth0", 65536, true, pcap.BlockForever)
    if err != nil {
        panic("Error opening pcap: " + err.Error())
    }

    datasource := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)

    //packets will be a channel of packets
    packets := datasource.Packets()

    for {
        select {
        case packet := <-packets:
            //We are decoding layers, and switching on the layer type
            err := parser.DecodeLayers(packet.Data(), &decodedLayers)
            for _, typ := range decodedLayers {
                switch typ {
                case layers.LayerTypeIPv4:
                    fmt.Printf("Source ip = %s - Destination ip = %s \n", ip4.SrcIP.String(), ip4.DstIP.String())
                case layers.LayerTypeTCP:
                    //Here, we can access tcp packet properties
                    fmt.Println("Capture tcp traffic")
                }
                //etc ....
            }
            if len(decodedLayers) == 0 {
                fmt.Println("Packet truncated")
            }

            //If the DecodeLayers is unable to decode the next layer type
            if err != nil {
                //fmt.Printf("Layer not found : %s", err)
            }
        }
    }

}
主程序包
进口(
“fmt”
“github.com/google/gopacket”
“github.com/google/gopacket/layers”
“github.com/google/gopacket/pcap”
“时间”
)
//我们想要解码的层
变量(
ip4.IPv4
以太网
tcp层.tcp
)
func main(){
//存储解码层的数组
decodedLayers:=[]gopacket.LayerType{}
//创建解析器
解析器:=gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet、ð、&ip4、&tcp)
//这里我们使用pcap在eth0接口上捕获数据包,我们也可以使用afpacket作为例子,这更有效
handle,err:=pcap.OpenLive(“eth0”,65536,true,pcap.BlockForever)
如果错误!=零{
死机(“打开pcap时出错:+err.Error())
}
数据源:=gopacket.NewPacketSource(句柄、层、层类型以太网)
//数据包将是数据包的一个通道
数据包:=datasource.packets()
为了{
挑选{
case packet:=就我个人而言,我使用它来捕获多个网络层,这个库非常令人印象深刻

使用gopacket时,可以通过指定多个网络层来捕获它们,例如
Ipv4
TCP
以太网
。。。 有关详细信息,请参阅

然后,您可以使用组成整个数据包的一组字节
packet.Data()
来分析层,然后打开数据包类型以执行一些操作

例如,在
eth0
上捕获多个网络层:

package main

import (
    "fmt"
    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
    "time"
)

//Layers we want to decode
var (
    ip4 layers.IPv4
    eth layers.Ethernet
    tcp layers.TCP
)

func main() {

    //Array to store decoded layers
    decodedLayers := []gopacket.LayerType{}

    //Create parser
    parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &tcp)

    //Here we use pcap to capture packet on eth0 interface, we can also use afpacket for example, which is more efficient
    handle, err := pcap.OpenLive("eth0", 65536, true, pcap.BlockForever)
    if err != nil {
        panic("Error opening pcap: " + err.Error())
    }

    datasource := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)

    //packets will be a channel of packets
    packets := datasource.Packets()

    for {
        select {
        case packet := <-packets:
            //We are decoding layers, and switching on the layer type
            err := parser.DecodeLayers(packet.Data(), &decodedLayers)
            for _, typ := range decodedLayers {
                switch typ {
                case layers.LayerTypeIPv4:
                    fmt.Printf("Source ip = %s - Destination ip = %s \n", ip4.SrcIP.String(), ip4.DstIP.String())
                case layers.LayerTypeTCP:
                    //Here, we can access tcp packet properties
                    fmt.Println("Capture tcp traffic")
                }
                //etc ....
            }
            if len(decodedLayers) == 0 {
                fmt.Println("Packet truncated")
            }

            //If the DecodeLayers is unable to decode the next layer type
            if err != nil {
                //fmt.Printf("Layer not found : %s", err)
            }
        }
    }

}
主程序包
进口(
“fmt”
“github.com/google/gopacket”
“github.com/google/gopacket/layers”
“github.com/google/gopacket/pcap”
“时间”
)
//我们想要解码的层
变量(
ip4.IPv4
以太网
tcp层.tcp
)
func main(){
//存储解码层的数组
decodedLayers:=[]gopacket.LayerType{}
//创建解析器
解析器:=gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet、ð、&ip4、&tcp)
//这里我们使用pcap在eth0接口上捕获数据包,我们也可以使用afpacket作为例子,这更有效
handle,err:=pcap.OpenLive(“eth0”,65536,true,pcap.BlockForever)
如果错误!=零{
死机(“打开pcap时出错:+err.Error())
}
数据源:=gopacket.NewPacketSource(句柄、层、层类型以太网)
//数据包将是数据包的一个通道
数据包:=datasource.packets()
为了{
挑选{

case packet:=我读了你的笔记,但你的答案必须是最好的,因为我想自己实现负载均衡器,所以我看到并听到很多数据包,然后转发