-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess.go.bak
140 lines (127 loc) · 2.79 KB
/
process.go.bak
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
package main
import (
"context"
"sync"
"time"
"github.com/ogios/simple-socket-server/server/normal"
"github.com/ogios/simple-proxy-server/log"
)
// address with connection
type Addrs struct {
Conn *normal.Conn
Origin string
Data []byte
}
// both server and client conn&addr&key&context
type ConnInfo struct {
Ctx context.Context
Cancel context.CancelFunc
Cond sync.Cond
Key string
Server Addrs
Client Addrs
}
// connection types
var (
TYPE_CLIENT uint8 = 1
TYPE_SERVER uint8 = 2
)
// global session
var (
SESSION_MAP map[string]*ConnInfo
MAP_COND sync.Cond
)
func init() {
SESSION_MAP = make(map[string]*ConnInfo)
MAP_COND = *sync.NewCond(&sync.Mutex{})
}
// process error and send it to the socket connetion
func DealError(err error, conn *normal.Conn) error {
defer conn.Close()
se := err.Error()
err = conn.So.AddBytes([]byte("error"))
if err == nil {
err = conn.So.AddBytes([]byte(se))
if err == nil {
err = conn.So.WriteTo(conn.Raw)
}
}
return err
}
// process a connection, if the other one is connected already then send addresses to each other
func Process(conn *normal.Conn, strkey string, data []byte, t uint8) error {
MAP_COND.L.Lock()
defer MAP_COND.L.Unlock()
log.Debug("prcess %d", t)
i, ok := SESSION_MAP[strkey]
if !ok {
log.Debug("No session registered, create one")
i = new(ConnInfo)
i.Cond = *sync.NewCond(&sync.Mutex{})
i.Key = strkey
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
i.Cancel = cancel
i.Ctx = ctx
}
log.Debug("creating address")
addr := &Addrs{
Origin: conn.Raw.RemoteAddr().String(),
Data: data,
Conn: conn,
}
log.Debug("adding address")
var check Addrs
switch t {
case TYPE_CLIENT:
i.Client = *addr
check = i.Server
case TYPE_SERVER:
i.Server = *addr
check = i.Client
}
SESSION_MAP[strkey] = i
if check.Origin != "" {
log.Debug("start communicating...")
err := i.Conmunicate()
if err != nil {
return err
}
}
return nil
}
// send addresses to each other
func (c *ConnInfo) Conmunicate() error {
defer delete(SESSION_MAP, c.Key)
defer c.Cancel()
defer c.Client.Conn.Close()
defer c.Server.Conn.Close()
log.Debug("adding client data...")
err := c.Client.Conn.So.AddBytes(c.Client.Data)
if err != nil {
return err
}
err = c.Client.Conn.So.AddBytes([]byte(c.Client.Origin))
if err != nil {
return err
}
log.Debug("sending to server...")
err = c.Client.Conn.So.WriteTo(c.Server.Conn.Raw)
if err != nil {
return err
}
log.Debug("adding server data...")
err = c.Server.Conn.So.AddBytes(c.Server.Data)
if err != nil {
return err
}
err = c.Server.Conn.So.AddBytes([]byte(c.Server.Origin))
if err != nil {
return err
}
log.Debug("sending to client...")
err = c.Server.Conn.So.WriteTo(c.Client.Conn.Raw)
if err != nil {
return err
}
return nil
}