mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
Add support for IPv6
This commit is contained in:
@@ -3,6 +3,7 @@ SOURCE_PATH = /go/src/github.com/buger/gor/
|
||||
RUN = docker run -v `pwd`:$(SOURCE_PATH) -p 0.0.0.0:8000:8000 -t -i gor
|
||||
BENCHMARK = BenchmarkRAWInput
|
||||
TEST = TestRawListenerBench
|
||||
VERSION = DEV-$(shell date +%s)
|
||||
|
||||
release: release-x64
|
||||
|
||||
@@ -53,7 +54,7 @@ profile_test:
|
||||
|
||||
# Used mainly for debugging, because docker container do not have access to parent machine ports
|
||||
run:
|
||||
$(RUN) go run $(SOURCE) --input-dummy=0 --output-http="http://localhost:9000" --input-raw :9000 --input-http :9000 --verbose --debug --middleware "./examples/middleware/echo.sh"
|
||||
$(RUN) go run $(SOURCE) --input-dummy=0 --output-http="http://localhost:9000" --input-raw 127.0.0.1:9000 --input-http 127.0.0.1:9000 --verbose --debug --middleware "./examples/middleware/echo.sh"
|
||||
|
||||
run-2:
|
||||
$(RUN) go run $(SOURCE) --input-file ./fixtures/requests.gor --output-dummy=0
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
raw "github.com/buger/gor/raw_socket_listener"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -62,8 +61,6 @@ func (i *RAWInput) Read(data []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (i *RAWInput) listen(address string) {
|
||||
address = strings.Replace(address, "[::]", "127.0.0.1", -1)
|
||||
|
||||
Debug("Listening for traffic on: " + address)
|
||||
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
|
||||
+16
-4
@@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/http/httputil"
|
||||
@@ -25,9 +26,20 @@ func TestRAWInput(t *testing.T) {
|
||||
wg := new(sync.WaitGroup)
|
||||
quit := make(chan int)
|
||||
|
||||
origin := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
|
||||
defer origin.Close()
|
||||
originAddr := strings.Replace(origin.Listener.Addr().String(), "[::]", "127.0.0.1", -1)
|
||||
listener, err := net.Listen("tcp", "[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
origin := &http.Server{
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}),
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
}
|
||||
go origin.Serve(listener)
|
||||
defer listener.Close()
|
||||
|
||||
originAddr := listener.Addr().String()
|
||||
|
||||
|
||||
var respCounter, reqCounter int64
|
||||
|
||||
@@ -51,7 +63,7 @@ func TestRAWInput(t *testing.T) {
|
||||
Plugins.Inputs = []io.Reader{input}
|
||||
Plugins.Outputs = []io.Writer{output}
|
||||
|
||||
client := NewHTTPClient(origin.URL, &HTTPClientConfig{})
|
||||
client := NewHTTPClient("http://" + listener.Addr().String(), &HTTPClientConfig{})
|
||||
|
||||
go Start(quit)
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ func (t *Listener) listen() {
|
||||
}
|
||||
return
|
||||
case data := <- t.packetsChan:
|
||||
packet := ParseTCPPacket(data[:4], data[4:])
|
||||
packet := ParseTCPPacket(data[:16], data[16:])
|
||||
t.processTCPPacket(packet)
|
||||
case <- gcTicker:
|
||||
now := time.Now()
|
||||
@@ -241,7 +241,7 @@ func findPcapDevice(addr string) (*pcap.Interface, error) {
|
||||
|
||||
for _, device := range devices {
|
||||
for _, address := range device.Addresses {
|
||||
if address.IP.String() == addr {
|
||||
if device.Name == addr || address.IP.String() == addr {
|
||||
return &device, nil
|
||||
}
|
||||
}
|
||||
@@ -272,8 +272,6 @@ func (t *Listener) readPcap() {
|
||||
|
||||
t.readyCh <- true
|
||||
|
||||
// log.Println(handle.Stats())
|
||||
|
||||
for {
|
||||
packet, err := source.NextPacket()
|
||||
|
||||
@@ -285,16 +283,31 @@ func (t *Listener) readPcap() {
|
||||
|
||||
// Skip ethernet layer, 14 bytes
|
||||
data := packet.Data()[14:]
|
||||
ihl := uint8(data[0]) & 0x0F
|
||||
version := uint8(data[0]) >> 4
|
||||
|
||||
// Truncated IP info
|
||||
if len(data) < int(ihl*4) {
|
||||
continue
|
||||
var srcIP []byte
|
||||
|
||||
if version == 4 {
|
||||
ihl := uint8(data[0]) & 0x0F
|
||||
|
||||
// Truncated IP info
|
||||
if len(data) < int(ihl*4) {
|
||||
continue
|
||||
}
|
||||
|
||||
srcIP = data[12:16]
|
||||
data = data[ihl*4:]
|
||||
} else {
|
||||
// Truncated IP info
|
||||
if len(data) < 40 {
|
||||
continue
|
||||
}
|
||||
|
||||
srcIP = data[8:24]
|
||||
|
||||
data = data[40:]
|
||||
}
|
||||
|
||||
srcIP := data[12:16]
|
||||
data = data[ihl*4:]
|
||||
|
||||
// Truncated TCP info
|
||||
if len(data) < 13 {
|
||||
continue
|
||||
@@ -305,9 +318,9 @@ func (t *Listener) readPcap() {
|
||||
// We need only packets with data inside
|
||||
// Check that the buffer is larger than the size of the TCP header
|
||||
if len(data) > int(dataOffset*4) {
|
||||
newBuf := make([]byte, len(data) + 4)
|
||||
copy(newBuf[:4], srcIP)
|
||||
copy(newBuf[4:], data)
|
||||
newBuf := make([]byte, len(data) + 16)
|
||||
copy(newBuf[:16], srcIP)
|
||||
copy(newBuf[16:], data)
|
||||
|
||||
t.packetsChan <- newBuf
|
||||
}
|
||||
@@ -343,8 +356,8 @@ func (t *Listener) readRAWSocket() {
|
||||
if n > 0 {
|
||||
if t.isValidPacket(buf[:n]) {
|
||||
newBuf := make([]byte, n + 4)
|
||||
copy(newBuf[4:], buf[:n])
|
||||
copy(newBuf[:4], []byte(addr.(*net.IPAddr).IP))
|
||||
copy(newBuf[16:], buf[:n])
|
||||
copy(newBuf[:16], []byte(addr.(*net.IPAddr).IP))
|
||||
|
||||
t.packetsChan <- newBuf
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ const (
|
||||
fNS
|
||||
)
|
||||
|
||||
type tcpID [12]byte
|
||||
type tcpID [24]byte
|
||||
|
||||
// TCPPacket provides tcp packet parser
|
||||
// Packet structure: http://en.wikipedia.org/wiki/Transmission_Control_Protocol
|
||||
@@ -48,10 +48,10 @@ func ParseTCPPacket(addr []byte, data []byte) (p *TCPPacket) {
|
||||
}
|
||||
|
||||
func (p *TCPPacket) GenID() {
|
||||
copy(p.ID[:4], p.Addr)
|
||||
copy(p.ID[4:], p.Raw[0:2]) // Src port
|
||||
copy(p.ID[6:], p.Raw[2:4]) // Dest port
|
||||
copy(p.ID[8:], p.Raw[8:12]) // Ack
|
||||
copy(p.ID[:16], p.Addr)
|
||||
copy(p.ID[16:], p.Raw[0:2]) // Src port
|
||||
copy(p.ID[18:], p.Raw[2:4]) // Dest port
|
||||
copy(p.ID[20:], p.Raw[8:12]) // Ack
|
||||
}
|
||||
|
||||
func (p *TCPPacket) UpdateAck(ack uint32) {
|
||||
@@ -73,16 +73,17 @@ func (t *TCPPacket) ParseBasic() {
|
||||
}
|
||||
|
||||
func (t *TCPPacket) Dump() []byte {
|
||||
buf := make([]byte, len(t.Data) + 16 + 4)
|
||||
buf := make([]byte, len(t.Data) + 16 + 16)
|
||||
tcpBuf := buf[16:]
|
||||
|
||||
binary.BigEndian.PutUint16(buf[6:8], t.DestPort)
|
||||
binary.BigEndian.PutUint16(buf[4:6], t.SrcPort)
|
||||
binary.BigEndian.PutUint16(tcpBuf[2:4], t.DestPort)
|
||||
binary.BigEndian.PutUint16(buf[0:2], t.SrcPort)
|
||||
|
||||
binary.BigEndian.PutUint32(buf[8:12], t.Seq)
|
||||
binary.BigEndian.PutUint32(buf[12:16], t.Ack)
|
||||
binary.BigEndian.PutUint32(buf[4:8], t.Seq)
|
||||
binary.BigEndian.PutUint32(buf[8:12], t.Ack)
|
||||
|
||||
buf[16] = 64
|
||||
copy(buf[20:], t.Data)
|
||||
tcpBuf[16] = 64
|
||||
copy(tcpBuf[20:], t.Data)
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user