| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | package dnstap
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import (
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	"net"
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 	"sync"
 | 
					
						
							|  |  |  | 	"testing"
 | 
					
						
							|  |  |  | 	"time"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-06 18:55:40 +08:00
										 |  |  | 	"github.com/coredns/coredns/plugin/pkg/reuseport"
 | 
					
						
							| 
									
										
										
										
											2019-12-07 07:47:18 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 	tap "github.com/dnstap/golang-dnstap"
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	fs "github.com/farsightsec/golang-framestream"
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | var (
 | 
					
						
							|  |  |  | 	msgType = tap.Dnstap_MESSAGE
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 	tmsg    = tap.Dnstap{Type: &msgType}
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | func accept(t *testing.T, l net.Listener, count int) {
 | 
					
						
							|  |  |  | 	server, err := l.Accept()
 | 
					
						
							|  |  |  | 	if err != nil {
 | 
					
						
							| 
									
										
										
										
											2018-05-07 22:47:25 +01:00
										 |  |  | 		t.Fatalf("Server accepted: %s", err)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 	dec, err := fs.NewDecoder(server, &fs.DecoderOptions{
 | 
					
						
							|  |  |  | 		ContentType:   []byte("protobuf:dnstap.Dnstap"),
 | 
					
						
							|  |  |  | 		Bidirectional: true,
 | 
					
						
							|  |  |  | 	})
 | 
					
						
							|  |  |  | 	if err != nil {
 | 
					
						
							| 
									
										
										
										
											2018-05-07 22:47:25 +01:00
										 |  |  | 		t.Fatalf("Server decoder: %s", err)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	for i := 0; i < count; i++ {
 | 
					
						
							|  |  |  | 		if _, err := dec.Decode(); err != nil {
 | 
					
						
							| 
									
										
										
										
											2018-05-07 22:47:25 +01:00
										 |  |  | 			t.Errorf("Server decode: %s", err)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	if err := server.Close(); err != nil {
 | 
					
						
							|  |  |  | 		t.Error(err)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | func TestTransport(t *testing.T) {
 | 
					
						
							| 
									
										
										
										
											2020-11-03 15:31:34 +01:00
										 |  |  | 	transport := [2][2]string{
 | 
					
						
							|  |  |  | 		{"tcp", ":0"},
 | 
					
						
							|  |  |  | 		{"unix", "dnstap.sock"},
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, param := range transport {
 | 
					
						
							| 
									
										
										
										
											2019-12-06 18:55:40 +08:00
										 |  |  | 		l, err := reuseport.Listen(param[0], param[1])
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 		if err != nil {
 | 
					
						
							|  |  |  | 			t.Fatalf("Cannot start listener: %s", err)
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var wg sync.WaitGroup
 | 
					
						
							|  |  |  | 		wg.Add(1)
 | 
					
						
							|  |  |  | 		go func() {
 | 
					
						
							|  |  |  | 			accept(t, l, 1)
 | 
					
						
							|  |  |  | 			wg.Done()
 | 
					
						
							|  |  |  | 		}()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 		dio := newIO(param[0], l.Addr().String())
 | 
					
						
							| 
									
										
										
										
											2020-11-03 15:31:34 +01:00
										 |  |  | 		dio.tcpTimeout = 10 * time.Millisecond
 | 
					
						
							|  |  |  | 		dio.flushTimeout = 30 * time.Millisecond
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 		dio.connect()
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-10 20:06:33 +02:00
										 |  |  | 		dio.Dnstap(&tmsg)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 		wg.Wait()
 | 
					
						
							|  |  |  | 		l.Close()
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 		dio.close()
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRace(t *testing.T) {
 | 
					
						
							|  |  |  | 	count := 10
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 15:31:34 +01:00
										 |  |  | 	l, err := reuseport.Listen("tcp", ":0")
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	if err != nil {
 | 
					
						
							|  |  |  | 		t.Fatalf("Cannot start listener: %s", err)
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	defer l.Close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var wg sync.WaitGroup
 | 
					
						
							|  |  |  | 	wg.Add(1)
 | 
					
						
							|  |  |  | 	go func() {
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 		accept(t, l, count)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 		wg.Done()
 | 
					
						
							|  |  |  | 	}()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 	dio := newIO("tcp", l.Addr().String())
 | 
					
						
							| 
									
										
										
										
											2020-11-03 15:31:34 +01:00
										 |  |  | 	dio.tcpTimeout = 10 * time.Millisecond
 | 
					
						
							|  |  |  | 	dio.flushTimeout = 30 * time.Millisecond
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 	dio.connect()
 | 
					
						
							|  |  |  | 	defer dio.close()
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 	wg.Add(count)
 | 
					
						
							|  |  |  | 	for i := 0; i < count; i++ {
 | 
					
						
							|  |  |  | 		go func() {
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 			tmsg := tap.Dnstap_MESSAGE
 | 
					
						
							| 
									
										
										
										
											2022-07-10 20:06:33 +02:00
										 |  |  | 			dio.Dnstap(&tap.Dnstap{Type: &tmsg})
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 			wg.Done()
 | 
					
						
							|  |  |  | 		}()
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 	wg.Wait()
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | func TestReconnect(t *testing.T) {
 | 
					
						
							|  |  |  | 	count := 5
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 15:31:34 +01:00
										 |  |  | 	l, err := reuseport.Listen("tcp", ":0")
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	if err != nil {
 | 
					
						
							|  |  |  | 		t.Fatalf("Cannot start listener: %s", err)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var wg sync.WaitGroup
 | 
					
						
							|  |  |  | 	wg.Add(1)
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 	go func() {
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 		accept(t, l, 1)
 | 
					
						
							|  |  |  | 		wg.Done()
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 	}()
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 	addr := l.Addr().String()
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 	dio := newIO("tcp", addr)
 | 
					
						
							| 
									
										
										
										
											2020-11-03 15:31:34 +01:00
										 |  |  | 	dio.tcpTimeout = 10 * time.Millisecond
 | 
					
						
							|  |  |  | 	dio.flushTimeout = 30 * time.Millisecond
 | 
					
						
							| 
									
										
										
										
											2020-11-05 14:37:16 +01:00
										 |  |  | 	dio.connect()
 | 
					
						
							|  |  |  | 	defer dio.close()
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-10 20:06:33 +02:00
										 |  |  | 	dio.Dnstap(&tmsg)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	wg.Wait()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 	// Close listener
 | 
					
						
							|  |  |  | 	l.Close()
 | 
					
						
							|  |  |  | 	// And start TCP listener again on the same port
 | 
					
						
							| 
									
										
										
										
											2019-12-06 18:55:40 +08:00
										 |  |  | 	l, err = reuseport.Listen("tcp", addr)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	if err != nil {
 | 
					
						
							|  |  |  | 		t.Fatalf("Cannot start listener: %s", err)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	defer l.Close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wg.Add(1)
 | 
					
						
							|  |  |  | 	go func() {
 | 
					
						
							| 
									
										
										
										
											2017-12-01 13:16:14 +02:00
										 |  |  | 		accept(t, l, 1)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 		wg.Done()
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | 	}()
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < count; i++ {
 | 
					
						
							| 
									
										
										
										
											2020-11-03 15:31:34 +01:00
										 |  |  | 		time.Sleep(100 * time.Millisecond)
 | 
					
						
							| 
									
										
										
										
											2022-07-10 20:06:33 +02:00
										 |  |  | 		dio.Dnstap(&tmsg)
 | 
					
						
							| 
									
										
										
										
											2017-11-28 00:36:14 +03:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 	wg.Wait()
 | 
					
						
							| 
									
										
										
										
											2017-09-26 17:45:33 +02:00
										 |  |  | }
 |