如何在L3网络层上收听?

时间:2017-09-01 17:47:26

标签: networking go ip load-balancing packet

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

我想创建一个负载均衡器,但不是在HTTP所在的L7层上,而是在IP网络所在的L3层上,以指示与特定服务器的连接,然后我可以TCP。< / p>

net.ListenIP是否正确用于侦听IP层上的数据包?

例如,它与较高的Listen("tcp")相同吗?这是我实现负载均衡器所需的正确方法吗?

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

如果没有告诉我使用哪个功能来侦听L3网络层以平衡负载到其他服务器。

2 个答案:

答案 0 :(得分:2)

reading the Docs之后,是的,此功能将帮助您接收IP数据包。

  

ListenIP就像是用于IP网络的ListenPacket。

ListenIPListenPacket("tcp")类似,但对于IP数据包。

对于IP数据包的结构,并使用它们,net包似乎没有。

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

gopacket中有Packet类型,允许使用网络层。

Packet.NetworkLayer().LayerContent()Packet.NetworkLayer().LayerPayload()将返回byte[],您可以按预期的structure of an IP packet解释。

注意既然我已经写完了这一切,我必须想象有人在那里编写了一个很好的叠加/包装来使这更容易。这只是我谷歌搜索10分钟的结果。也许其他人会用更好的工具/方法回答

答案 1 :(得分:2)

就个人而言,我使用gopacket来捕获多个网络层,这个库非常令人印象深刻。

当您使用gopacket时,您可以通过指定它们来捕获多个网络图层,例如Ipv4TCPEthernet ... 有关详细信息,请参阅layers packet

然后,您将能够使用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) } } } } 上捕获多个网络层:

 $store_name = isset($_POST['store_name']) ? $_POST['store_name'] : null;

      $sql = "insert into user_feedback (store_name,name,feedback) values ('$store_name','$name','$feedback')";