-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexample_star_test.go
177 lines (156 loc) · 4.22 KB
/
example_star_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package netem_test
import (
"context"
"fmt"
"io"
"log"
"net"
"net/http"
"github.com/ooni/netem"
)
// This example shows how to create a star topology, a DNS server, and
// an HTTPS server. Then we create an HTTPS client and we use such a
// client to fetch a very important message from the server.
func Example_starTopologyHTTPSAndDNS() {
// Create a star topology for our hosts.
topology := netem.MustNewStarTopology(&netem.NullLogger{})
defer topology.Close()
// Add client stack to topology. Note that we don't need to
// close the clientStack: the topology will do that.
clientStack, err := topology.AddHost(
"10.0.0.1", // host IP address
"8.8.8.8", // host DNS resolver IP address
&netem.LinkConfig{}, // link with no PLR, RTT, DPI
)
if err != nil {
log.Fatal(err)
}
// Add DNS server stack to topology.
dnsServerStack, err := topology.AddHost(
"8.8.8.8",
"8.8.8.8", // this host is its own DNS resolver
&netem.LinkConfig{},
)
if err != nil {
log.Fatal(err)
}
// Add HTTPS server stack to topology.
httpsServerStack, err := topology.AddHost(
"5.4.3.21",
"8.8.8.8",
&netem.LinkConfig{},
)
if err != nil {
log.Fatal(err)
}
// spawn a DNS server with the required configuration.
dnsConfig := netem.NewDNSConfig()
dnsConfig.AddRecord("tyrell.wellick.name", "tw01.fsociety.com.", "5.4.3.21")
dnsServer, err := netem.NewDNSServer(
&netem.NullLogger{},
dnsServerStack,
"8.8.8.8",
dnsConfig,
)
if err != nil {
log.Fatal(err)
}
defer dnsServer.Close()
// spawn an HTTP server with the required configuration
mux := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Bonsoir, Elliot!"))
})
httpsAddr := &net.TCPAddr{
IP: net.ParseIP("5.4.3.21"),
Port: 443,
}
httpsListener, err := httpsServerStack.ListenTCP("tcp", httpsAddr)
if err != nil {
log.Fatal(err)
}
httpsServer := &http.Server{
Handler: mux,
TLSConfig: httpsServerStack.MustNewServerTLSConfig("tyrell.wellick.name"),
}
go httpsServer.ServeTLS(httpsListener, "", "") // empty string: use .TLSConfig
defer httpsServer.Close()
// create an HTTP transport using the clientStack
txp := netem.NewHTTPTransport(clientStack)
// Note that all the code that follows is standard Go code that
// would work for any implementation of http.RoundTripper.
// create HTTP request
req, err := http.NewRequest("GET", "https://tyrell.wellick.name/", nil)
if err != nil {
log.Fatal(err)
}
// perform HTTP round trip
resp, err := txp.RoundTrip(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// read the response body
data, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%d\n", resp.StatusCode)
fmt.Printf("%s\n", string(data))
// Output:
// 200
// Bonsoir, Elliot!
//
}
// This example shows how DNS servers implement whoami.v4.powerdns.org
func Example_starTopologyDNSWhoami() {
// Create a star topology for our hosts.
topology := netem.MustNewStarTopology(&netem.NullLogger{})
defer topology.Close()
// Add client stack to topology. Note that we don't need to
// close the clientStack: the topology will do that.
clientStack, err := topology.AddHost(
"130.192.91.211", // host IP address
"8.8.8.8", // host DNS resolver IP address
&netem.LinkConfig{}, // link with no PLR, RTT, DPI
)
if err != nil {
log.Fatal(err)
}
// Add DNS server stack to topology.
dnsServerStack, err := topology.AddHost(
"8.8.8.8",
"8.8.8.8", // this host is its own DNS resolver
&netem.LinkConfig{},
)
if err != nil {
log.Fatal(err)
}
// spawn a DNS server with empty configuration.
dnsConfig := netem.NewDNSConfig()
dnsServer, err := netem.NewDNSServer(
&netem.NullLogger{},
dnsServerStack,
"8.8.8.8",
dnsConfig,
)
if err != nil {
log.Fatal(err)
}
defer dnsServer.Close()
// create the DNS query to use
query := netem.NewDNSRequestA("whoami.v4.powerdns.org")
// issue a DNS request to the server
response, err := netem.DNSRoundTrip(context.Background(), clientStack, "8.8.8.8", query)
if err != nil {
log.Fatal(err)
}
// parse the DNS response
addrs, _, err := netem.DNSParseResponse(query, response)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", addrs)
// Output:
// [130.192.91.211]
//
}