aboutsummaryrefslogtreecommitdiff
path: root/etc/tftp.lua
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2011-05-25 20:57:22 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2011-05-25 20:57:22 +0000
commit3a8ba90dfb0c2eb224f317dd692ede426691e72a (patch)
treefe1cc5379a2e0e031663fe9c15d908653844bc73 /etc/tftp.lua
parentbce60be30fe8e9c1b0eb33128c23c93d7bca5303 (diff)
downloadluasocket-3a8ba90dfb0c2eb224f317dd692ede426691e72a.tar.gz
luasocket-3a8ba90dfb0c2eb224f317dd692ede426691e72a.tar.bz2
luasocket-3a8ba90dfb0c2eb224f317dd692ede426691e72a.zip
Saving before big changes to support IPv6.
Diffstat (limited to 'etc/tftp.lua')
-rw-r--r--etc/tftp.lua68
1 files changed, 34 insertions, 34 deletions
diff --git a/etc/tftp.lua b/etc/tftp.lua
index c028b20..4051e74 100644
--- a/etc/tftp.lua
+++ b/etc/tftp.lua
@@ -35,18 +35,18 @@ local OP_INV = {"RRQ", "WRQ", "DATA", "ACK", "ERROR"}
35-- Packet creation functions 35-- Packet creation functions
36----------------------------------------------------------------------------- 36-----------------------------------------------------------------------------
37local function RRQ(source, mode) 37local function RRQ(source, mode)
38 return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) 38 return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0)
39end 39end
40 40
41local function WRQ(source, mode) 41local function WRQ(source, mode)
42 return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) 42 return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0)
43end 43end
44 44
45local function ACK(block) 45local function ACK(block)
46 local low, high 46 local low, high
47 low = math.mod(block, 256) 47 low = math.mod(block, 256)
48 high = (block - low)/256 48 high = (block - low)/256
49 return char(0, OP_ACK, high, low) 49 return char(0, OP_ACK, high, low)
50end 50end
51 51
52local function get_OP(dgram) 52local function get_OP(dgram)
@@ -58,16 +58,16 @@ end
58-- Packet analysis functions 58-- Packet analysis functions
59----------------------------------------------------------------------------- 59-----------------------------------------------------------------------------
60local function split_DATA(dgram) 60local function split_DATA(dgram)
61 local block = byte(dgram, 3)*256 + byte(dgram, 4) 61 local block = byte(dgram, 3)*256 + byte(dgram, 4)
62 local data = string.sub(dgram, 5) 62 local data = string.sub(dgram, 5)
63 return block, data 63 return block, data
64end 64end
65 65
66local function get_ERROR(dgram) 66local function get_ERROR(dgram)
67 local code = byte(dgram, 3)*256 + byte(dgram, 4) 67 local code = byte(dgram, 3)*256 + byte(dgram, 4)
68 local msg 68 local msg
69 _,_, msg = string.find(dgram, "(.*)\000", 5) 69 _,_, msg = string.find(dgram, "(.*)\000", 5)
70 return string.format("error code %d: %s", code, msg) 70 return string.format("error code %d: %s", code, msg)
71end 71end
72 72
73----------------------------------------------------------------------------- 73-----------------------------------------------------------------------------
@@ -77,40 +77,40 @@ local function tget(gett)
77 local retries, dgram, sent, datahost, dataport, code 77 local retries, dgram, sent, datahost, dataport, code
78 local last = 0 78 local last = 0
79 socket.try(gett.host, "missing host") 79 socket.try(gett.host, "missing host")
80 local con = socket.try(socket.udp()) 80 local con = socket.try(socket.udp())
81 local try = socket.newtry(function() con:close() end) 81 local try = socket.newtry(function() con:close() end)
82 -- convert from name to ip if needed 82 -- convert from name to ip if needed
83 gett.host = try(socket.dns.toip(gett.host)) 83 gett.host = try(socket.dns.toip(gett.host))
84 con:settimeout(1) 84 con:settimeout(1)
85 -- first packet gives data host/port to be used for data transfers 85 -- first packet gives data host/port to be used for data transfers
86 local path = string.gsub(gett.path or "", "^/", "") 86 local path = string.gsub(gett.path or "", "^/", "")
87 path = url.unescape(path) 87 path = url.unescape(path)
88 retries = 0 88 retries = 0
89 repeat 89 repeat
90 sent = try(con:sendto(RRQ(path, "octet"), gett.host, gett.port)) 90 sent = try(con:sendto(RRQ(path, "octet"), gett.host, gett.port))
91 dgram, datahost, dataport = con:receivefrom() 91 dgram, datahost, dataport = con:receivefrom()
92 retries = retries + 1 92 retries = retries + 1
93 until dgram or datahost ~= "timeout" or retries > 5 93 until dgram or datahost ~= "timeout" or retries > 5
94 try(dgram, datahost) 94 try(dgram, datahost)
95 -- associate socket with data host/port 95 -- associate socket with data host/port
96 try(con:setpeername(datahost, dataport)) 96 try(con:setpeername(datahost, dataport))
97 -- default sink 97 -- default sink
98 local sink = gett.sink or ltn12.sink.null() 98 local sink = gett.sink or ltn12.sink.null()
99 -- process all data packets 99 -- process all data packets
100 while 1 do 100 while 1 do
101 -- decode packet 101 -- decode packet
102 code = get_OP(dgram) 102 code = get_OP(dgram)
103 try(code ~= OP_ERROR, get_ERROR(dgram)) 103 try(code ~= OP_ERROR, get_ERROR(dgram))
104 try(code == OP_DATA, "unhandled opcode " .. code) 104 try(code == OP_DATA, "unhandled opcode " .. code)
105 -- get data packet parts 105 -- get data packet parts
106 local block, data = split_DATA(dgram) 106 local block, data = split_DATA(dgram)
107 -- if not repeated, write 107 -- if not repeated, write
108 if block == last+1 then 108 if block == last+1 then
109 try(sink(data)) 109 try(sink(data))
110 last = block 110 last = block
111 end 111 end
112 -- last packet brings less than 512 bytes of data 112 -- last packet brings less than 512 bytes of data
113 if string.len(data) < 512 then 113 if string.len(data) < 512 then
114 try(con:send(ACK(block))) 114 try(con:send(ACK(block)))
115 try(con:close()) 115 try(con:close())
116 try(sink(nil)) 116 try(sink(nil))
@@ -118,13 +118,13 @@ local function tget(gett)
118 end 118 end
119 -- get the next packet 119 -- get the next packet
120 retries = 0 120 retries = 0
121 repeat 121 repeat
122 sent = try(con:send(ACK(last))) 122 sent = try(con:send(ACK(last)))
123 dgram, err = con:receive() 123 dgram, err = con:receive()
124 retries = retries + 1 124 retries = retries + 1
125 until dgram or err ~= "timeout" or retries > 5 125 until dgram or err ~= "timeout" or retries > 5
126 try(dgram, err) 126 try(dgram, err)
127 end 127 end
128end 128end
129 129
130local default = { 130local default = {