-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go
74 lines (67 loc) · 1.6 KB
/
client.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
package main
import (
"bytes"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"log"
"net"
)
func clientConf() *tls.Config {
cert := loadPrivK("client")
pool := x509.NewCertPool()
pool.AddCert(loadPubK("server"))
return &tls.Config{
// Client presents this to the server
Certificates: []tls.Certificate{cert},
// RootCAs are used by clients to validate server certificates. They
// are the public keys of trusted root certificate authorities.
RootCAs: pool,
// ServerName used to verify the server's hostname on returned certificates
// It can also be an IP address.
ServerName: SAddr,
}
}
func client(ready <-chan string, done <-chan bool, errc chan<- error) {
printf := func(fm string, v ...interface{}) {
log.Printf("client: "+fm+"\n", v...)
}
esend := func(fm string, v ...interface{}) {
errc <- fmt.Errorf("client: "+fm, v...)
}
raddr := <-ready
if raddr == "" {
esend("error on the server side")
return
}
printf("dial -> %s", raddr)
lip, err := net.ResolveTCPAddr("tcp", CSocket)
if err != nil {
esend("failed to resolve local IP: %s", err)
return
}
d := &net.Dialer{
LocalAddr: lip,
}
conn, err := tls.DialWithDialer(d, "tcp", raddr, clientConf())
laddr := "(unknown)"
if conn != nil {
laddr = conn.LocalAddr().String()
}
printf("conn %s -> %s", laddr, raddr)
if err != nil {
esend("error dialing conn from %s -> %s (error %s)", laddr, raddr, err)
return
}
go func() {
defer conn.Close()
buf := new(bytes.Buffer)
_, err = io.Copy(buf, conn)
printf("from server -> %q", buf.String())
errc <- err
}()
fmt.Fprintf(conn, "hi")
conn.CloseWrite()
<-done
}