axa  2.2.0
Farsight Security Advanced Exchange Access (AXA)
axa_wire

Detailed Description

axa_wire is an interface for wire protocol data types and function declarations.

Data Structures

struct  axa_io
 AXA I/O context. More...
 

Macros

#define AXA_TAG_STRLEN   10
 maximum human readable tag string length More...
 
#define AXA_P_OP_STRLEN   20
 maximum buffer size for text representations of AXA opcodes More...
 
#define AXA_P_STRLEN
 Maximum buffer or string length from axa_p_to_str() More...
 
#define AXA_IO_TYPE_UNIX_STR   "unix"
 AXA I/O type prefix: UNIX domain socket unix:/path/to/socket. More...
 
#define AXA_IO_TYPE_TCP_STR   "tcp"
 AXA I/O type prefix: TCP connection tcp:hostname,port. More...
 
#define AXA_IO_TYPE_SSH_STR   "ssh"
 AXA I/O type prefix: ssh connection ssh:[user@]host. More...
 
#define AXA_IO_TYPE_TLS_STR   "tls"
 AXA I/O type prefix: tls connection tls:certfile,keyfile[,certdir]@host[,port]. More...
 
#define AXA_IO_TYPE_APIKEY_STR   "apikey"
 AXA I/O type prefix: apikey/tls apikey:hostname,port. More...
 
#define AXA_IO_OPENED(io)   ((io)->i_fd >= 0)
 Check than an AXA I/O context is open. More...
 
#define AXA_IO_CONNECTED(io)   (AXA_IO_OPENED(io) && (io)->connected)
 check that an AXA I/O context is open and connected More...
 

Typedefs

typedef struct axa_io axa_io_t
 AXA I/O context. More...
 

Enumerations

enum  axa_p_direction_t
 AXA protocol data direction, to or from SRA or RAD server. More...
 
enum  axa_io_type_t
 AXA I/O context types. More...
 
enum  axa_io_result_t
 I/O result codes. More...
 

Functions

bool axa_parse_watch (axa_emsg_t *emsg, axa_p_watch_t *watch, size_t *watch_len, const char *arg)
 Parse an AXA watch definition. More...
 
bool axa_parse_rad_watch (axa_emsg_t *emsg, axa_p_watch_t *watch, size_t *watch_len, const char *arg)
 Parse a RAD watch definition. More...
 
bool axa_parse_anom (axa_emsg_t *emsg, axa_p_anom_t *anom, size_t *anom_len, const char *arg)
 Parse an AXA anomaly detection module definition. More...
 
char * axa_watch_ip_to_str (char *buf, size_t buf_len, int af, const void *addr, size_t alen, uint prefix)
 Convert a network address to its string equivalent. More...
 
char * axa_watch_to_str (char *buf, size_t buf_len, const axa_p_watch_t *watch, size_t watch_len)
 Convert a watch to its string equivalent. More...
 
const char * axa_tag_to_str (char *buf, size_t buf_len, axa_tag_t tag)
 Convert AXA tag to its string equivalent. More...
 
const char * axa_op_to_str (char *buf, size_t buf_len, axa_p_op_t op)
 Convert AXA opcode to its string equivalent. More...
 
const char * axa_opt_to_str (char *buf, size_t buflen, axa_p_opt_type_t opt)
 Convert AXA option type to its string equivalent. More...
 
const char * axa_tag_op_to_str (char *buf, size_t buf_len, axa_tag_t tag, axa_p_op_t op)
 Convert AXA tag and opcode to their string equivalents separated by ' '. More...
 
bool axa_ipdg_parse (const uint8_t *pkt_data, size_t caplen, axa_p_ch_t ch, axa_socku_t *dst, axa_socku_t *src, char *cmt, size_t cmt_len)
 Parse a raw IP datagram. More...
 
char * axa_p_to_str (char *buf, size_t buf_len, bool print_op, const axa_p_hdr_t *hdr, const axa_p_body_t *cmd)
 Convert AXA protocol message to a string representation. More...
 
bool axa_ck_hdr (axa_emsg_t *emsg, const axa_p_hdr_t *hdr, const char *label, axa_p_direction_t dir)
 Check the header of an AXA message. More...
 
size_t axa_make_hdr (axa_emsg_t *emsg, axa_p_hdr_t *hdr, axa_p_pvers_t pvers, axa_tag_t tag, axa_p_op_t op, size_t b1_len, size_t b2_len, axa_p_direction_t dir)
 Populate an AXA header including converting to wire byte order. More...
 
bool axa_ck_body (axa_emsg_t *emsg, axa_p_op_t op, const axa_p_body_t *body, size_t body_len)
 Sanity check the body of an AXA message. More...
 
void axa_io_init (axa_io_t *io)
 Initialize an AXA I/O structure with default values. More...
 
void axa_io_pvers_get (axa_io_t *io, uint8_t *pvers)
 Get the current protocol version used by an AXA I/O structure. More...
 
void axa_io_pvers_set (axa_io_t *io, uint8_t pvers)
 Set the current protocol version that will be used by an AXA I/O structure. More...
 
void axa_recv_flush (axa_io_t *io)
 Flush and free the received AXA protocol message (if any) in an I/O context from a previous use of axa_recv_buf() or axa_input(). More...
 
void axa_io_close (axa_io_t *io)
 Close the connection and flush and release buffers. More...
 
axa_io_result_t axa_recv_buf (axa_emsg_t *emsg, axa_io_t *io)
 Receive some of an AXA request or response into a fixed header buffer and a dynamic body buffer. More...
 
axa_io_result_t axa_send (axa_emsg_t *emsg, axa_io_t *io, axa_tag_t tag, axa_p_op_t op, axa_p_hdr_t *hdr, const void *b1, size_t b1_len, const void *b2, size_t b2_len)
 Send an AXA request or response to the client or the server. More...
 
axa_io_result_t axa_send_flush (axa_emsg_t *emsg, axa_io_t *io)
 Flush the pending output buffer. More...
 
void axa_send_save (axa_io_t *io, size_t done, const axa_p_hdr_t *hdr, const void *b1, size_t b1_len, const void *b2, size_t b2_len)
 Save un-transmitted data. More...
 
axa_io_result_t axa_io_wait (axa_emsg_t *emsg, axa_io_t *io, time_t wait_ms, bool keepalive, bool tun)
 Wait for some input activity. More...
 
axa_io_result_t axa_input (axa_emsg_t *emsg, axa_io_t *io, time_t wait_ms)
 Wait for and read an AXA message from the server into the client context. More...
 
const char * axa_io_tunerr (axa_io_t *io)
 Get error or debugging messages from the tunnel (e.g. More...
 
bool axa_tls_certs_dir (axa_emsg_t *emsg, const char *dir)
 Get or set TLS certificates directory. More...
 
const char * axa_tls_cipher_list (axa_emsg_t *emsg, const char *list)
 Get or set cipher list for TLS transport. More...
 
const char * axa_apikey_cipher_list (axa_emsg_t *emsg, const char *list)
 Get or set TLS cipher list for apikey transport. More...
 
bool axa_tls_init (axa_emsg_t *emsg, bool srvr, bool threaded)
 Initialize the AXA TLS code including creating an SSL_CTX. More...
 
bool axa_apikey_init (axa_emsg_t *emsg, bool srvr, bool threaded)
 Initialize the AXA TLS code including creating an SSL_CTX for the apikey transport. More...
 
void axa_io_cleanup (void)
 Clean up AXA I/O functions including freeing TLS data. More...
 

Macro Definition Documentation

◆ AXA_TAG_STRLEN

#define AXA_TAG_STRLEN   10

maximum human readable tag string length

◆ AXA_P_OP_STRLEN

#define AXA_P_OP_STRLEN   20

maximum buffer size for text representations of AXA opcodes

◆ AXA_P_STRLEN

#define AXA_P_STRLEN
Value:
(sizeof("dns=")-1+2+1025+1 \
+sizeof(AXA_P_WATCH_STR_SHARED)+1)

Maximum buffer or string length from axa_p_to_str()

◆ AXA_IO_TYPE_UNIX_STR

#define AXA_IO_TYPE_UNIX_STR   "unix"

AXA I/O type prefix: UNIX domain socket unix:/path/to/socket.

◆ AXA_IO_TYPE_TCP_STR

#define AXA_IO_TYPE_TCP_STR   "tcp"

AXA I/O type prefix: TCP connection tcp:hostname,port.

◆ AXA_IO_TYPE_SSH_STR

#define AXA_IO_TYPE_SSH_STR   "ssh"

AXA I/O type prefix: ssh connection ssh:[user@]host.

◆ AXA_IO_TYPE_TLS_STR

#define AXA_IO_TYPE_TLS_STR   "tls"

AXA I/O type prefix: tls connection tls:certfile,keyfile[,certdir]@host[,port].

◆ AXA_IO_TYPE_APIKEY_STR

#define AXA_IO_TYPE_APIKEY_STR   "apikey"

AXA I/O type prefix: apikey/tls apikey:hostname,port.

◆ AXA_IO_OPENED

#define AXA_IO_OPENED (   io)    ((io)->i_fd >= 0)

Check than an AXA I/O context is open.

Parameters
[in]ioaddress of an I/O context

◆ AXA_IO_CONNECTED

#define AXA_IO_CONNECTED (   io)    (AXA_IO_OPENED(io) && (io)->connected)

check that an AXA I/O context is open and connected

Parameters
[in]ioaddress of an I/O context

Typedef Documentation

◆ axa_io_t

typedef struct axa_io axa_io_t

AXA I/O context.

Enumeration Type Documentation

◆ axa_p_direction_t

AXA protocol data direction, to or from SRA or RAD server.

Enumerator
AXA_P_TO_SRA 

To SRA server.

AXA_P_FROM_SRA 

From SRA server.

AXA_P_TO_RAD 

To RAD server.

AXA_P_FROM_RAD 

From RAD server.

◆ axa_io_type_t

AXA I/O context types.

Enumerator
AXA_IO_TYPE_UNKN 

invalid

AXA_IO_TYPE_UNIX 

UNIX domain socket.

AXA_IO_TYPE_TCP 

TCP/IP socket.

AXA_IO_TYPE_SSH 

ssh pipe

AXA_IO_TYPE_TLS 

TLS connection.

AXA_IO_TYPE_APIKEY 

apikey/TLS

◆ axa_io_result_t

I/O result codes.

Enumerator
AXA_IO_ERR 

print emsg

AXA_IO_OK 

operation finished

AXA_IO_BUSY 

incomplete; poll() & try again

AXA_IO_TUNERR 

get text via axa_io_tunerr()

AXA_IO_KEEPALIVE 

need to send keepalive NOP

Function Documentation

◆ axa_parse_watch()

bool axa_parse_watch ( axa_emsg_t emsg,
axa_p_watch_t watch,
size_t *  watch_len,
const char *  arg 
)

Parse an AXA watch definition.

If there is a problem, the function will return false and emsg->c will contain a relevant error message – except when the watch makes no sense. In that case, emsg->c[0] == '\0'.

Parameters
[out]emsgthe reason if something went wrong
[out]watchparsed result
[out]watch_lensizeof(*watch) - sizeof(watch->pat);
[in]arguser specified string to watch for, must be NULL terminated
Return values
truesuccess
falseerror; check emsg

◆ axa_parse_rad_watch()

bool axa_parse_rad_watch ( axa_emsg_t emsg,
axa_p_watch_t watch,
size_t *  watch_len,
const char *  arg 
)

Parse a RAD watch definition.

If there is a problem, the function will return false and emsg->c will contain a relevant error message – except when the watch is unrecognized. In that case, emsg->c[0] == '\0'.

Parameters
[out]emsgif something goes wrong, this will contain the reason
[out]watchparsed result
[out]watch_lensizeof(*watch) - sizeof(watch->pat);
[in]arguser specified string to watch for, must be NULL terminated
Return values
truesuccess
falseerror, check emsg

◆ axa_parse_anom()

bool axa_parse_anom ( axa_emsg_t emsg,
axa_p_anom_t anom,
size_t *  anom_len,
const char *  arg 
)

Parse an AXA anomaly detection module definition.

If there is a problem, the function will return false and emsg->c will contain a relevant error message – except when the watch is unrecognized. In that case, emsg->c[0] == '\0'.

Parameters
[out]emsgif something goes wrong, this will contain the reason
[out]anomparsed result
[out]anom_lensizeof(*watch) - sizeof(watch->pat);
[in]arguser specified string to watch for, must be NULL terminated
Return values
truesuccess
falseerror, check emsg

◆ axa_watch_ip_to_str()

char* axa_watch_ip_to_str ( char *  buf,
size_t  buf_len,
int  af,
const void *  addr,
size_t  alen,
uint  prefix 
)

Convert a network address to its string equivalent.

Parameters
[out]bufwill hold the watch string
[in]buf_lenlength of buf
[in]afthe address family
[in]addrthe address to convert
[in]alensize of the addr parameter
[in]prefixaddress prefix length
Returns
buf

◆ axa_watch_to_str()

char* axa_watch_to_str ( char *  buf,
size_t  buf_len,
const axa_p_watch_t watch,
size_t  watch_len 
)

Convert a watch to its string equivalent.

Parameters
[out]bufwill hold the watch string
[in]buf_lenlength of buf
[in]watchthe watch to convert
[in]watch_lensize of the watch parameter
Returns
buf

◆ axa_tag_to_str()

const char* axa_tag_to_str ( char *  buf,
size_t  buf_len,
axa_tag_t  tag 
)

Convert AXA tag to its string equivalent.

If the tag is AXA_TAG_NONE, buf will contain "*".

Parameters
[out]bufwill hold the tag string
[in]buf_lenlength of buf (should be AXA_TAG_STRLEN)
[in]tagthe AXA tag value
Returns
buf

◆ axa_op_to_str()

const char* axa_op_to_str ( char *  buf,
size_t  buf_len,
axa_p_op_t  op 
)

Convert AXA opcode to its string equivalent.

If the opcode is unknown to AXA, the buffer will contain the string "unknown op n".

Parameters
[out]bufwill hold the opcode string
[in]buf_lenlength of buf (should be AXA_P_OP_STRLEN)
[in]opthe opcode to look up
Returns
buf

◆ axa_opt_to_str()

const char* axa_opt_to_str ( char *  buf,
size_t  buflen,
axa_p_opt_type_t  opt 
)

Convert AXA option type to its string equivalent.

If the opcode is unknown to AXA, the buffer will contain the string "unknown option type #n".

Parameters
[out]bufwill hold the option type string
[in]buflenlength of buf (should be AXA_P_OP_STRLEN)
[in]optthe option type to look up
Returns
buf

◆ axa_tag_op_to_str()

const char* axa_tag_op_to_str ( char *  buf,
size_t  buf_len,
axa_tag_t  tag,
axa_p_op_t  op 
)

Convert AXA tag and opcode to their string equivalents separated by ' '.

Parameters
[out]buffor the result
[in]buf_lenlength of buf (should be AXA_P_OP_STRLEN)
[in]tagthe tag to convert
[in]opthe opcode to convert
Returns
buf

◆ axa_ipdg_parse()

bool axa_ipdg_parse ( const uint8_t *  pkt_data,
size_t  caplen,
axa_p_ch_t  ch,
axa_socku_t dst,
axa_socku_t src,
char *  cmt,
size_t  cmt_len 
)

Parse a raw IP datagram.

Parameters
[in]pkt_dataIP datagram
[in]caplencaptured length of the packet
[in]chhost byte order SIE channel on which it arrived
[out]dstbuffer for destination address and port number
[out]srcbuffer for destination address and port number
[out]cmtbuffer for error messages, optional protocol name,or other optional comments; always '\0' terminated
[in]cmt_lenlength of cmt; 80 is good
Return values
truefound something to decode into the src and dst buffers
falseonly the cmt buffer is set

◆ axa_p_to_str()

char* axa_p_to_str ( char *  buf,
size_t  buf_len,
bool  print_op,
const axa_p_hdr_t hdr,
const axa_p_body_t cmd 
)

Convert AXA protocol message to a string representation.

Return NULL if the protocol message is invalid.

Parameters
[out]bufwill hold the message string
[in]buf_lenlength of buf (should be AXA_P_STRLEN)
[in]print_opif true, prepend the tag and opcode to string
[in]hdrprotocol header
[in]cmdAXA command to parse into a string
Returns
buf

◆ axa_ck_hdr()

bool axa_ck_hdr ( axa_emsg_t emsg,
const axa_p_hdr_t hdr,
const char *  label,
axa_p_direction_t  dir 
)

Check the header of an AXA message.

Return false if the header is invalid.

Parameters
[out]emsgthe reason if the return value is false
[in]hdrAXA protocol header (will be filled in)
[in]labellabel for error message
[in]dirdirection of header for error message
Returns
bool header is ok

◆ axa_make_hdr()

size_t axa_make_hdr ( axa_emsg_t emsg,
axa_p_hdr_t hdr,
axa_p_pvers_t  pvers,
axa_tag_t  tag,
axa_p_op_t  op,
size_t  b1_len,
size_t  b2_len,
axa_p_direction_t  dir 
)

Populate an AXA header including converting to wire byte order.

Parameters
[out]emsgthe reason if the return value is 0
[out]hdrAXA protocol header (will be filled in)
[in]pversprotocol version
[in]tagAXA tag
[in]opAXA opcode
[in]b1_lenlength of first message body (if any)
[in]b2_lenlength of second message body (if any)
[in]dirthe direction of the flow (to/from SRA to to/from RAD)
Returns
0 for bad parameters or total length of AXA message or sizeof(hdr)+b1_len+b2_len in wire byte order

◆ axa_ck_body()

bool axa_ck_body ( axa_emsg_t emsg,
axa_p_op_t  op,
const axa_p_body_t body,
size_t  body_len 
)

Sanity check the body of an AXA message.

Depending on the opcode, function checks such things as NULL termination on strings, sane channel numbers, legal options, watch semantics, etc.

Parameters
[out]emsgif something goes wrong, this will contain the reason
[in]opopcode
[in]bodymessage body
[in]body_lenmessage body length
Return values
truemessage is legal
falsesomething's wrong, check emsg

◆ axa_io_init()

void axa_io_init ( axa_io_t io)

Initialize an AXA I/O structure with default values.

When re-initializing, all buffers must have been freed and file descriptors closed.

Parameters
[in]ioaddress of an I/O context

◆ axa_io_pvers_get()

void axa_io_pvers_get ( axa_io_t io,
uint8_t *  pvers 
)

Get the current protocol version used by an AXA I/O structure.

Parameters
[in]ioaddress of an I/O context
[out]pversthe protocol version

◆ axa_io_pvers_set()

void axa_io_pvers_set ( axa_io_t io,
uint8_t  pvers 
)

Set the current protocol version that will be used by an AXA I/O structure.

Note this function can have drastic consequences if a connection was previously established and the protocol version is changed to something the other end does not understand.

Parameters
[in]ioaddress of an I/O context
[out]pversthe protocol version to change to

◆ axa_recv_flush()

void axa_recv_flush ( axa_io_t io)

Flush and free the received AXA protocol message (if any) in an I/O context from a previous use of axa_recv_buf() or axa_input().

Parameters
[in]ioaddress of an I/O context

◆ axa_io_close()

void axa_io_close ( axa_io_t io)

Close the connection and flush and release buffers.

Parameters
[in]ioaddress of an I/O context

◆ axa_recv_buf()

axa_io_result_t axa_recv_buf ( axa_emsg_t emsg,
axa_io_t io 
)

Receive some of an AXA request or response into a fixed header buffer and a dynamic body buffer.

This function can stall until a byte is read, so call axa_io_wait() first or axa_input() instead. axa_recv_flush() must be called to discard the AXA message before another use of this function.

Parameters
[out]emsgif something goes wrong, this will contain the reason
[in]ioAXA IO context
Return values
AXA_IO_OKmessage in io->recv_hdr, recv_body, and recv_len
AXA_IO_BUSYtry again after axa_io_wait()
AXA_IO_ERRfatal error or EOF

◆ axa_send()

axa_io_result_t axa_send ( axa_emsg_t emsg,
axa_io_t io,
axa_tag_t  tag,
axa_p_op_t  op,
axa_p_hdr_t hdr,
const void *  b1,
size_t  b1_len,
const void *  b2,
size_t  b2_len 
)

Send an AXA request or response to the client or the server.

The message is in 1, 2, or 3 parts. hdr always points to the AXA protocol header to build b1 and b1_len specify an optional second part b2 and b2_len specify the optional third part. The second part must be present if the third part is.

Parameters
[out]emsgan error message for a result of AXA_IO_ERR
[in]ioAXA I/O context
[in]tagAXA tag
[in]opAXA opcode
[out]hdrAXA protocol header to be built or NULL
[in]b1NULL or first part of AXA message after header
[in]b1_lenlength of b1
[in]b2NULL or second part of the message
[in]b2_lenlength of b2
Return values
AXA_IO_OKfinished or output saved
AXA_IO_BUSYnothing sent; axa_io_wait() and try again
AXA_IO_ERRfatal error

◆ axa_send_flush()

axa_io_result_t axa_send_flush ( axa_emsg_t emsg,
axa_io_t io 
)

Flush the pending output buffer.

Parameters
[out]emsgcontains an error message for return values other than AXA_IO_OK
[in]ioAXA I/O context
Return values
AXA_IO_OKfinished
AXA_IO_BUSYincomplete; io->{i,o}_events ready for axa_io_wait()
AXA_IO_ERRfatal error

◆ axa_send_save()

void axa_send_save ( axa_io_t io,
size_t  done,
const axa_p_hdr_t hdr,
const void *  b1,
size_t  b1_len,
const void *  b2,
size_t  b2_len 
)

Save un-transmitted data.

Parameters
[in]ioAXA I/O context
[in]donebytes already handled
[out]hdrAXA protocol header
[in]b1NULL or first part of AXA message after header
[in]b1_lenlength of b1
[in]b2NULL or second part of the message
[in]b2_lenlength of b2

◆ axa_io_wait()

axa_io_result_t axa_io_wait ( axa_emsg_t emsg,
axa_io_t io,
time_t  wait_ms,
bool  keepalive,
bool  tun 
)

Wait for some input activity.

Parameters
[out]emsgif something goes wrong, this will contain the reason
[in]ioaddress of the AXA I/O context
[in]wait_mswait no longer than this many milliseconds
[in]keepalivetrue to wake up to send a keep-alive
[in]tuntrue to pay attention if possible to tunnel messages
Return values
oneof axa_io_result_t

◆ axa_input()

axa_io_result_t axa_input ( axa_emsg_t emsg,
axa_io_t io,
time_t  wait_ms 
)

Wait for and read an AXA message from the server into the client context.

axa_recv_flush() must be called to discard the AXA message in the client context before another use of this function.

Parameters
[out]emsgif something goes wrong, this will contain the reason
[in]ioaddress of the AXA I/O context
[in]wait_msmilliseconds to wait
Return values
oneof axa_io_result_t

◆ axa_io_tunerr()

const char* axa_io_tunerr ( axa_io_t io)

Get error or debugging messages from the tunnel (e.g.

ssh).

Parameters
[in]ioaddress of the AXA I/O context
Return values
NULLor pointer to '\0' terminated text

◆ axa_tls_certs_dir()

bool axa_tls_certs_dir ( axa_emsg_t emsg,
const char *  dir 
)

Get or set TLS certificates directory.

Parameters
[out]emsgthe reason if something went wrong
[in]dirdirectory containing TLS certificate key files or NULL
Return values
truesuccess
falseerror; check emsg

◆ axa_tls_cipher_list()

const char* axa_tls_cipher_list ( axa_emsg_t emsg,
const char *  list 
)

Get or set cipher list for TLS transport.

Parameters
[out]emsgthe reason if something went wrong
[in]listOpenSSL format cipher list or NULL
Return values
NULLimplies an error; check emsg
newvalue if not NULL

◆ axa_apikey_cipher_list()

const char* axa_apikey_cipher_list ( axa_emsg_t emsg,
const char *  list 
)

Get or set TLS cipher list for apikey transport.

Parameters
[out]emsgthe reason if something went wrong
[in]listOpenSSL format cipher list or NULL
Return values
NULLimplies an error; check emsg
newvalue if not NULL

◆ axa_tls_init()

bool axa_tls_init ( axa_emsg_t emsg,
bool  srvr,
bool  threaded 
)

Initialize the AXA TLS code including creating an SSL_CTX.

Parameters
[out]emsgthe reason if something went wrong
[in]srvrtrue if running as a server.
[in]threadedtrue if using pthreads.
Return values
truesuccess
falseerror; check emsg

◆ axa_apikey_init()

bool axa_apikey_init ( axa_emsg_t emsg,
bool  srvr,
bool  threaded 
)

Initialize the AXA TLS code including creating an SSL_CTX for the apikey transport.

Parameters
[out]emsgthe reason if something went wrong
[in]srvrtrue if running as a server.
[in]threadedtrue if using pthreads.
Return values
truesuccess
falseerror; check emsg

◆ axa_io_cleanup()

void axa_io_cleanup ( void  )

Clean up AXA I/O functions including freeing TLS data.