-
Notifications
You must be signed in to change notification settings - Fork 5
/
conn.go
97 lines (86 loc) · 1.96 KB
/
conn.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
package gossl
/*
#include "openssl/ssl.h"
#include "openssl/err.h"
#cgo pkg-config: openssl
*/
import "C"
import "time"
import "net"
import "fmt"
var _ = fmt.Println
type Conn struct {
conn net.Conn
ssl *SSL
bio *BIO
err error
handshakeCompleted bool
}
func (self *Conn) Conn() net.Conn {
return self.conn
}
// basic connection, must call either NewServerConn or NewClientConn
func newConn(ctx *Context, conn net.Conn) (*Conn, error) {
self := &Conn{ssl: NewSSL(ctx),
bio: NewBIO(BIOConn()),
conn: conn}
self.bio.SetAppData(self)
self.ssl.SetBIO(self.bio, self.bio)
return self, nil
}
// create a new server connection
func NewServerConn(ctx *Context, conn net.Conn) (*Conn, error) {
sslConn, err := newConn(ctx, conn)
if err != nil {
return nil, err
}
sslConn.ssl.SetAcceptState()
return sslConn, nil
}
// create a new client connection
func NewClientConn(ctx *Context, conn net.Conn) (*Conn, error) {
sslConn, err := newConn(ctx, conn)
if err != nil {
return nil, err
}
sslConn.ssl.SetConnectState()
return sslConn, nil
}
func (self *Conn) Close() error {
return self.ssl.Shutdown()
}
func (self *Conn) LocalAddr() net.Addr {
return self.conn.LocalAddr()
}
func (self *Conn) RemoteAddr() net.Addr {
return self.conn.RemoteAddr()
}
func (self *Conn) Read(b []byte) (int, error) {
if err := self.Handshake(); err != nil {
fmt.Printf("handshake failed %s;\n", err)
return 0, err
}
return self.ssl.Read(b)
}
func (self *Conn) Write(b []byte) (int, error) {
if err := self.Handshake(); err != nil {
return 0, err
}
return self.ssl.Write(b)
}
func (self *Conn) SetDeadline(t time.Time) error {
return nil
}
func (self *Conn) SetReadDeadline(t time.Time) error {
return nil
}
func (self *Conn) SetWriteDeadline(t time.Time) error {
return nil
}
func (self *Conn) Handshake() (err error) {
if !self.handshakeCompleted {
err = self.ssl.Handshake()
self.handshakeCompleted = true
}
return
}