英文:
how to listen on L3 network layer?
问题
我正在创建一个聊天应用程序的后端,并希望考虑到可扩展性。
我想创建一个负载均衡器,但不是在位于HTTP的L7层上,而是在位于IP网络的L3层上,以将连接定向到特定的服务器,然后我可以进行TCP连接。
net.ListenIP
是用于在IP层上监听数据包的正确函数吗?
它和更高层的Listen("tcp")
一样吗?这是我需要实现负载均衡器的正确方法吗?
有没有关于数据包结构的参考,以便我能够从中获取源IP和目标IP并将其转发?
如果没有,请告诉我在L3网络层上监听并将负载均衡到其他服务器的函数是什么。
英文:
I am creating a chat application backend and want to take into consideration the scalability.
I wanted to create a load balancer but not on the L7 layer where HTTP is located, but on the L3 layer where IP network is located to direct connections to the specific servers where I can then make TCP
.
Is net.ListenIP
the correct function to use to listen to the packets on the IP layer?
Is it the same as the higher Listen("tcp")
for example? Is it the right method that I need to implement the load balancer?
Is there a reference to how the packet is structured so I am able get out from it the source and destination IPs to forward them?
If not tell me which function to use to listen on the L3 network layer to balance the loads to other servers.
答案1
得分: 3
个人而言,我使用gopacket来捕获多个网络层,这个库非常令人印象深刻。
当你使用gopacket时,可以通过指定网络层来捕获多个网络层,例如Ipv4
、TCP
、Ethernet
等。
更多信息请参见层包。
然后,你可以使用packet.Data()
来分析你的层,它是构成整个数据包的一组字节,然后根据数据包类型执行一些操作。
例如,在eth0
上捕获多个网络层:
package main
import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"time"
)
//我们想要解码的层
var (
ip4 layers.IPv4
eth layers.Ethernet
tcp layers.TCP
)
func main() {
//用于存储解码后的层的数组
decodedLayers := []gopacket.LayerType{}
//创建解析器
parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &tcp)
//在这里,我们使用pcap在eth0接口上捕获数据包,我们也可以使用更高效的afpacket
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 := datasource.Packets()
for {
select {
case packet := <-packets:
//我们正在解码层,并根据层类型进行切换
err := parser.DecodeLayers(packet.Data(), &decodedLayers)
for _, typ := range decodedLayers {
switch typ {
case layers.LayerTypeIPv4:
fmt.Printf("源IP = %s - 目标IP = %s \n", ip4.SrcIP.String(), ip4.DstIP.String())
case layers.LayerTypeTCP:
//在这里,我们可以访问TCP数据包的属性
fmt.Println("捕获TCP流量")
}
//等等....
}
if len(decodedLayers) == 0 {
fmt.Println("数据包被截断")
}
//如果DecodeLayers无法解码下一个层类型
if err != nil {
//fmt.Printf("未找到层:%s", err)
}
}
}
}
英文:
Personally, I use gopacket in order to capture multiple network layers, and this library is very impressive.
When you're using gopacket, you are able to capture multiple network layers by specifying them, for example Ipv4
, TCP
, Ethernet
...
For more information, see layers packet.
Then, you will be able to analyze your layers by using packet.Data()
, which is a set of bytes that make up this entire packet, and then switch on the packet type to perform some actions.
For example, capturing multiple network layers on 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)
}
}
}
}
答案2
得分: 2
在阅读了文档之后,是的,这个函数将帮助你接收IP数据包。
ListenIP
类似于 ListenPacket("tcp")
,但用于 IP 数据包。
至于 IP 数据包的结构和处理,net
包似乎没有提供相关功能。
有另一个包叫做 gopacket
,看起来可以帮助你读取和修改任何层次的数据包。
在 gopacket
中有一个 Packet
类型,可以用来处理网络层。
Packet.NetworkLayer().LayerContent()
和 Packet.NetworkLayer().LayerPayload()
分别返回 byte[]
,你可以按照期望的 IP 数据包结构 进行解释。
注意:现在我写完了整个回答,我想必定有人已经写了一个很好的覆盖/包装工具来简化这个过程。这只是我花了10分钟在谷歌上搜索的结果。也许其他人会用更好的工具/方法来回答。
英文:
After reading the Docs, yes this function will help you receive IP Packets.
>ListenIP acts like ListenPacket for IP networks.
ListenIP
is similar to ListenPacket("tcp")
but for IP packets.
As for the structure of IP packets, and working with them, the net
package doesn't seem to have that.
There's another package gopacket
which looks like it will be able to help you read and modify packets from any layer.
In gopacket
there is a Packet
type, which allows working with the network layer.
Packet.NetworkLayer().LayerContent()
and Packet.NetworkLayer().LayerPayload()
will each return byte[]
which you can interpret by the expected structure of an IP packet.
Note: Now that I've written this whole thing I have to imagine somebody out there has written a nice overlay/wrapper to make this easier. This is just the result of me Googling for 10 minutes. Maybe somebody else will answer with a better tool/method
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论