Repository navigation
Expand file tree
/
Copy pathnetwork.lua
More file actions
128 lines (125 loc) · 2.92 KB
/
Copy pathnetwork.lua
File metadata and controls
128 lines (125 loc) · 2.92 KB
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
local select = require 'common.select'
local proto = require 'common.protocol'
local function parseAddress(address, client)
if address:sub(1,1) == '@' then
return {
protocol = 'unix',
address = address:sub(2),
client = client,
}
end
local ipv4, port = address:match("(%d+%.%d+%.%d+%.%d+):(%d+)")
if ipv4 then
return {
protocol = 'tcp',
address = ipv4,
port = tonumber(port),
client = client,
}
end
local ipv6, port = address:match("%[([%d:a-fA-F]+)%]:(%d+)")
if ipv6 then
return {
protocol = 'tcp6',
address = ipv6,
port = tonumber(port),
client = client,
}
end
error "Invalid address."
end
local function open(address, client)
local t = parseAddress(address, client)
local m = {}
local session
local srvfd
local write = ''
local e_send = function(_) end
local e_close = function() end
local stat = {}
function t.event(status, fd)
if status == 'connect start' then
assert(t.client)
srvfd = fd
return
end
if status == 'connect failed' then
assert(t.client)
select.close(srvfd)
select.wantconnect(t)
return
end
if status == 'close' then
if session == fd then
if t.client then
srvfd = nil
select.wantconnect(t)
end
e_close()
session = nil
end
return
end
if session then
fd:close()
return
end
session = fd
select.send(session, write)
write = ''
end
if t.client then
select.wantconnect(t)
else
srvfd = assert(select.listen(t))
end
function m.event_in(f)
e_send = f
end
function m.event_close(f)
e_close = function()
write = ''
stat = {debug=stat.debug}
f()
end
end
function m.update()
select.update(0)
local data = m.recv()
if data ~= '' then
e_send(data)
end
return true
end
function m.send(data)
if not session then
write = write .. data
return
end
select.send(session, data)
end
function m.recv()
if not session then
return ''
end
return select.recv(session)
end
function m.close()
select.close(session)
write = ''
end
function m.debug(v)
stat.debug = v
end
function m.sendmsg(pkg)
m.send(proto.send(pkg, stat))
end
function m.recvmsg()
return proto.recv(m.recv(), stat)
end
function m.closeall()
select.closeall()
end
return m
end
return open