Module rspamd_tcp
Module rspamd_tcp
Rspamd TCP module represents generic TCP asynchronous client available from LUA code. This module hides all complexity: DNS resolving, sessions management, zero-copy text transfers and so on under the hood. It can work in partial or complete modes:
- partial mode is used when you need to call a continuation routine each time data is available for read
- complete mode calls for continuation merely when all data is read from socket (e.g. when a server sends reply and closes a connection)
Example:
local logger = require "rspamd_logger"
local tcp = require "rspamd_tcp"
rspamd_config.SYM = function(task)
local function cb(err, data)
logger.infox('err: %1, data: %2', err, tostring(data))
end
tcp.request({
task = task,
host = "google.com",
port = 80,
data = {"GET / HTTP/1.0\r\n", "Host: google.com\r\n", "\r\n"},
callback = cb})
end
-- New TCP syntax test
rspamd_config:register_symbol({
name = 'TCP_TEST',
type = "normal",
callback = function(task)
local logger = require "rspamd_logger"
local function rcpt_done_cb(err, data, conn)
logger.errx(task, 'RCPT: got reply: %s, error: %s', data, err)
conn:close()
end
local function rcpt_cb(err, conn)
logger.errx(task, 'written rcpt, error: %s', err)
conn:add_read(rcpt_done_cb, '\r\n')
end
local function from_done_cb(err, data, conn)
logger.errx(task, 'FROM: got reply: %s, error: %s', data, err)
conn:add_write(rcpt_cb, 'RCPT TO: <test@yandex.ru>\r\n')
end
local function from_cb(err, conn)
logger.errx(task, 'written from, error: %s', err)
conn:add_read(from_done_cb, '\r\n')
end
local function hello_done_cb(err, data, conn)
logger.errx(task, 'HELO: got reply: %s, error: %s', data, err)
conn:add_write(from_cb, 'MAIL FROM: <>\r\n')
end
local function hello_cb(err, conn)
logger.errx(task, 'written hello, error: %s', err)
conn:add_read(hello_done_cb, '\r\n')
end
local function init_cb(err, data, conn)
logger.errx(task, 'got reply: %s, error: %s', data, err)
conn:add_write(hello_cb, 'HELO example.com\r\n')
end
tcp.request{
task = task,
callback = init_cb,
stop_pattern = '\r\n',
host = 'mx.yandex.ru',
port = 25
end,
priority = 10,
})
Brief content:
Functions:
Function | Description |
---|---|
rspamd_tcp.connect_sync() | . |
rspamd_tcp.request({params}) | This function creates and sends TCP request to the specified host and port,. |
rspamd_tcp.connect_sync({params}) | Creates new pseudo-synchronous connection to the specific address:port. |
Methods:
Method | Description |
---|---|
tcp:close() | . |
tcp:add_read(callback, [pattern]) | . |
tcp:add_write(callback, data) | . |
tcp:shift_callback() | . |
tcp:starttls([no_verify]) | . |
tcp:close() | . |
read_once() | . |
eof() | . |
shutdown() | . |
write() | . |
Functions
The module rspamd_tcp
defines the following functions.
Function rspamd_tcp.connect_sync()
Creates pseudo-synchronous TCP connection. Each method of the connection requiring IO, becomes a yielding point, i.e. current thread Lua thread is get suspended and resumes as soon as IO is done
This class represents low-level API, using of "lua_tcp_sync" module is recommended.
Parameters:
No parameters
Returns:
No return
Example:
local rspamd_tcp = require "rspamd_tcp"
local logger = require "rspamd_logger"
local function http_simple_tcp_symbol(task)
local err
local is_ok, connection = rspamd_tcp.connect_sync {
task = task,
host = '127.0.0.1',
timeout = 20,
port = 18080,
ssl = false, -- If SSL connection is needed
ssl_verify = true, -- set to false if verify is not needed
is_ok, err = connection:write('GET /request_sync HTTP/1.1\r\nConnection: keep-alive\r\n\r\n')
logger.errx(task, 'write %1, %2', is_ok, err)
if not is_ok then
logger.errx(task, 'write error: %1', err)
end
local data
is_ok, data = connection:read_once();
logger.errx(task, 'read_once: is_ok: %1, data: %2', is_ok, data)
is_ok, err = connection:write("POST /request2 HTTP/1.1\r\n\r\n")
logger.errx(task, 'write[2] %1, %2', is_ok, err)
is_ok, data = connection:read_once();
logger.errx(task, 'read_once[2]: is_ok %1, data: %2', is_ok, data)
connection:close()
end
rspamd_config:register_symbol({
name = 'SIMPLE_TCP_TEST',
score = 1.0,
callback = http_simple_tcp_symbol,
no_squeeze = true
})
Back to module description.
Function rspamd_tcp.request({params})
This function creates and sends TCP request to the specified host and port, resolves hostname (if needed) and invokes continuation callback upon data received from the remote peer. This function accepts table of arguments with the following attributes
task
: rspamd task objects (impliespool
,session
,ev_base
andresolver
arguments)ev_base
: event base (if no task specified)resolver
: DNS resolver (no task)session
: events session (no task)host
: IP or name of the peer (required)port
: remote port to usedata
: a table of strings orrspamd_text
objects that contains data piecescallback
: continuation function (required)on_connect
: callback called on connection successtimeout
: floating point value that specifies timeout for IO operations in secondspartial
: boolean flag that specifies that callback should be called on any data portion receivedstop_pattern
: stop reading on finding a certain pattern (e.g. \r\n.\r\n for smtp)shutdown
: half-close socket after writing (boolean: default false)read
: read response after sending request (boolean: default true)upstream
: optional upstream object that would be used to get an address
Parameters:
No parameters
Returns:
{boolean}
: true if request has been sent
Back to module description.
Function rspamd_tcp.connect_sync({params})
Creates new pseudo-synchronous connection to the specific address:port
task
: rspamd task objects (impliespool
,session
,ev_base
andresolver
arguments)ev_base
: event base (if no task specified)resolver
: DNS resolver (no task)session
: events session (no task)config
: config (no task)host
: IP or name of the peer (required)port
: remote port to usetimeout
: floating point value that specifies timeout for IO operations in seconds
Parameters:
No parameters
Returns:
{boolean}
: true if request has been sent
Back to module description.
Methods
The module rspamd_tcp
defines the following methods.
Method tcp:close()
Closes TCP connection
Parameters:
No parameters
Returns:
No return
Back to module description.
Method tcp:add_read(callback, [pattern])
Adds new read event to the tcp connection
Parameters:
callback {function}
: to be called when data is readpattern {string}
: optional stop pattern
Returns:
No return
Back to module description.
Method tcp:add_write(callback, data)
Adds new write event to the tcp connection
Parameters:
optional {function}
: callback to be called when data is completely writtendata {table/string/text}
: to send to a remote server
Returns:
No return
Back to module description.
Method tcp:shift_callback()
Shifts the current callback and go to the next one (if any)
Parameters:
No parameters
Returns:
No return
Back to module description.
Method tcp:starttls([no_verify])
Starts tls connection
Parameters:
no_verify {boolean}
: used to skip ssl verification
Returns:
No return
Back to module description.
Method tcp:close()
Closes TCP connection
Parameters:
No parameters
Returns:
No return
Back to module description.
Method read_once()
Performs one read operation. If syscall returned with EAGAIN/EINT, restarts the operation, so it always returns either data or error.
Parameters:
No parameters
Returns:
No return
Back to module description.
Method eof()
True if last IO operation ended with EOF, i.e. endpoint closed connection
Parameters:
No parameters
Returns:
No return
Back to module description.
Method shutdown()
Half-shutdown TCP connection
Parameters:
No parameters
Returns:
No return
Back to module description.
Method write()
Writes data into the stream. If syscall returned with EAGAIN/EINT restarts the operation. If performs write() until all the passed data is written completely.
Parameters:
No parameters
Returns:
No return
Back to module description.
Back to top.