@@ -8,8 +8,8 @@ package guess
8
8
9
9
import (
10
10
"encoding/binary"
11
- "net"
12
11
12
+ "github.com/pkg/errors"
13
13
"golang.org/x/sys/unix"
14
14
15
15
"github.com/elastic/beats/libbeat/common"
@@ -30,19 +30,16 @@ import (
30
30
31
31
func init () {
32
32
if err := Registry .AddGuess (
33
- & guessSockaddrIn6 {
34
- address : net.TCPAddr {
35
- IP : []byte {0xFD , 0xE5 , 0x7C , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xAA , 0xBB , 0xCC , 0xDD },
36
- Port : 0xFEEF ,
37
- },
38
- }); err != nil {
33
+ & guessSockaddrIn6 {}); err != nil {
39
34
panic (err )
40
35
}
41
36
}
42
37
43
38
type guessSockaddrIn6 struct {
44
- ctx Context
45
- address net.TCPAddr
39
+ ctx Context
40
+ loopback helper.IPv6Loopback
41
+ clientAddr , serverAddr unix.SockaddrInet6
42
+ client , server int
46
43
}
47
44
48
45
// Name of this guess.
@@ -88,25 +85,60 @@ func (g *guessSockaddrIn6) Probes() ([]helper.ProbeDef, error) {
88
85
}
89
86
90
87
// Prepare is a no-op.
91
- func (g * guessSockaddrIn6 ) Prepare (ctx Context ) error {
88
+ func (g * guessSockaddrIn6 ) Prepare (ctx Context ) ( err error ) {
92
89
g .ctx = ctx
90
+ g .loopback , err = helper .NewIPv6Loopback ()
91
+ if err != nil {
92
+ return errors .Wrap (err , "detect IPv6 loopback failed" )
93
+ }
94
+ defer func () {
95
+ if err != nil {
96
+ g .loopback .Cleanup ()
97
+ }
98
+ }()
99
+ clientIP , err := g .loopback .AddRandomAddress ()
100
+ if err != nil {
101
+ return errors .Wrap (err , "failed adding first device address" )
102
+ }
103
+ serverIP , err := g .loopback .AddRandomAddress ()
104
+ if err != nil {
105
+ return errors .Wrap (err , "failed adding second device address" )
106
+ }
107
+ copy (g .clientAddr .Addr [:], clientIP )
108
+ copy (g .serverAddr .Addr [:], serverIP )
109
+
110
+ if g .client , g .clientAddr , err = createSocket6WithProto (unix .SOCK_STREAM , g .clientAddr ); err != nil {
111
+ return errors .Wrap (err , "error creating server" )
112
+ }
113
+ if g .server , g .serverAddr , err = createSocket6WithProto (unix .SOCK_STREAM , g .serverAddr ); err != nil {
114
+ return errors .Wrap (err , "error creating client" )
115
+ }
116
+ if err = unix .Listen (g .server , 1 ); err != nil {
117
+ return errors .Wrap (err , "error in listen" )
118
+ }
93
119
return nil
94
120
}
95
121
96
122
// Terminate is a no-op.
97
123
func (g * guessSockaddrIn6 ) Terminate () error {
124
+ unix .Close (g .client )
125
+ unix .Close (g .server )
126
+ if err := g .loopback .Cleanup (); err != nil {
127
+ return err
128
+ }
98
129
return nil
99
130
}
100
131
101
132
// Trigger performs a connection attempt on the random address.
102
133
func (g * guessSockaddrIn6 ) Trigger () error {
103
- dialer := net. Dialer {
104
- Timeout : g . ctx . Timeout ,
134
+ if err := unix . Connect ( g . client , & g . serverAddr ); err != nil {
135
+ return errors . Wrap ( err , "connect failed" )
105
136
}
106
- conn , err := dialer . Dial ( "tcp" , g . address . String () )
107
- if err = = nil {
108
- conn . Close ( )
137
+ fd , _ , err := unix . Accept ( g . server )
138
+ if err ! = nil {
139
+ return errors . Wrap ( err , "accept failed" )
109
140
}
141
+ unix .Close (fd )
110
142
return nil
111
143
}
112
144
@@ -124,13 +156,13 @@ func (g *guessSockaddrIn6) Extract(ev interface{}) (common.MapStr, bool) {
124
156
return nil , false
125
157
}
126
158
127
- binary .BigEndian .PutUint16 (needle [:], uint16 (g .address .Port ))
159
+ binary .BigEndian .PutUint16 (needle [:], uint16 (g .serverAddr .Port ))
128
160
offsetOfPort := indexAligned (arr , needle [:], offsetOfFamily + 2 , 2 )
129
161
if offsetOfPort == - 1 {
130
162
return nil , false
131
163
}
132
164
133
- offsetOfAddr := indexAligned (arr , g .address . IP , offsetOfPort + 2 , 1 )
165
+ offsetOfAddr := indexAligned (arr , g .serverAddr . Addr [:] , offsetOfPort + 2 , 1 )
134
166
if offsetOfAddr == - 1 {
135
167
return nil , false
136
168
}
0 commit comments