TAPI for miscellaneous remote calls

Overview

// typedefs

typedef struct tapi_rand_gen tapi_rand_gen;
typedef struct tapi_pat_sender tapi_pat_sender;
typedef struct tapi_pat_receiver tapi_pat_receiver;
typedef struct te_saved_mtu te_saved_mtu;

// structs

struct tapi_pat_receiver;
struct tapi_pat_sender;
struct tapi_rand_gen;
struct te_saved_mtu;

// global functions

static void tapi_rand_gen_set(tapi_rand_gen* arg, int min, int max, tarpc_bool once);
void tapi_pat_sender_init(tapi_pat_sender* p);
void tapi_pat_receiver_init(tapi_pat_receiver* p);
bool rpc_find_func(rcf_rpc_server* rpcs, const char* func_name);
int rpc_vlan_get_parent(rcf_rpc_server* rpcs, const char* vlan_ifname, char* parent_ifname);
int rpc_bond_get_slaves(rcf_rpc_server* rpcs, const char* bond_ifname, tqh_strings* slaves, int* slaves_num);
tarpc_ssize_t rpc_get_sizeof(rcf_rpc_server* rpcs, const char* type_name);
bool rpc_protocol_info_cmp(rcf_rpc_server* rpcs, const uint8_t* buf1, const uint8_t* buf2, tarpc_bool is_wide1, tarpc_bool is_wide2);
rpc_ptr rpc_get_addrof(rcf_rpc_server* rpcs, const char* name);
uint64_t rpc_get_var(rcf_rpc_server* rpcs, const char* name, tarpc_size_t size);
void rpc_set_var(rcf_rpc_server* rpcs, const char* name, tarpc_size_t size, uint64_t val);
int rpc_simple_sender(rcf_rpc_server* handle, int s, int size_min, int size_max, int size_rnd_once, int delay_min, int delay_max, int delay_rnd_once, int time2run, uint64_t* sent, int ignore_err);
int rpc_simple_receiver(rcf_rpc_server* handle, int s, uint32_t time2run, uint64_t* received);
int rpc_pattern_sender(rcf_rpc_server* rpcs, int s, tapi_pat_sender* args);
int rpc_pattern_receiver(rcf_rpc_server* rpcs, int s, tapi_pat_receiver* args);
int rpc_wait_readable(rcf_rpc_server* rpcs, int s, uint32_t timeout);
int rpc_recv_verify(rcf_rpc_server* handle, int s, const char* gen_data_fname, uint64_t start);
int rpc_iomux_flooder(rcf_rpc_server* handle, int* sndrs, int sndnum, int* rcvrs, int rcvnum, int bulkszs, int time2run, int time2wait, int iomux, uint64_t* tx_stat, uint64_t* rx_stat);
int rpc_send_flooder_iomux(rcf_rpc_server* rpcs, int sock, iomux_func iomux, tarpc_send_function send_func, bool msg_dontwait, int packet_size, int duration, uint64_t* packets, uint32_t* errors);
int rpc_iomux_echoer(rcf_rpc_server* handle, int* sockets, int socknum, int time2run, int iomux, uint64_t* tx_stat, uint64_t* rx_stat);
int rpc_iomux_splice(rcf_rpc_server* rpcs, int iomux, int fd_in, int fd_out, size_t len, int flags, int time2run);
ssize_t rpc_socket_to_file(rcf_rpc_server* handle, int sock, const char* path_name, long timeout);
int64_t rpc_copy_fd2fd(rcf_rpc_server* rpcs, int out_fd, int in_fd, int timeout, uint64_t count);
int rpc_ftp_open(rcf_rpc_server* handle, char* uri, bool rdonly, bool passive, int offset, int* sock);
int rpc_ftp_close(rcf_rpc_server* handle, int sock);
int rpc_overfill_buffers_data(rcf_rpc_server* rpcs, int sock, uint64_t* sent, iomux_func iomux, uint8_t** sent_data);
static int rpc_overfill_buffers_gen(rcf_rpc_server* rpcs, int sock, uint64_t* sent, iomux_func iomux);
static int rpc_overfill_buffers(rcf_rpc_server* rpcs, int sock, uint64_t* sent);
int rpc_drain_fd(rcf_rpc_server* rpcs, int fd, size_t size, int time2wait, uint64_t* read);
int rpc_drain_fd_duration(rcf_rpc_server* rpcs, int fd, size_t size, int time2wait, unsigned int duration, uint64_t* read);
int rpc_drain_fd_simple(rcf_rpc_server* rpcs, int fd, uint64_t* read);
int rpc_overfill_fd(rcf_rpc_server* rpcs, int write_end, uint64_t* sent);
int rpc_read_fd2te_dbuf_append(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_dbuf* dbuf);
int rpc_read_fd2te_dbuf(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_dbuf* dbuf);
int rpc_read_fd(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, void** buf, size_t* read);
int rpc_read_fd2te_string_append(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_string* testr);
int rpc_read_fd2te_string(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_string* testr);
void rpc_vm_trasher(rcf_rpc_server* rpcs, bool start);
void rpc_set_buf_gen(rcf_rpc_server* rpcs, const uint8_t* src_buf, size_t len, rpc_ptr dst_buf, size_t dst_off);
static void rpc_set_buf(rcf_rpc_server* rpcs, const uint8_t* src_buf, size_t len, rpc_ptr dst_buf);
static void rpc_set_buf_off(rcf_rpc_server* rpcs, const uint8_t* src_buf, size_t len, rpc_ptr_off* dst_buf);
void rpc_set_buf_pattern_gen(rcf_rpc_server* rpcs, int pattern, size_t len, rpc_ptr dst_buf, size_t dst_off);
static void rpc_set_buf_pattern(rcf_rpc_server* rpcs, int pattern, size_t len, rpc_ptr dst_buf);
static void rpc_set_buf_pattern_off(rcf_rpc_server* rpcs, int pattern, size_t len, rpc_ptr_off* dst_buf);
void rpc_get_buf_gen(rcf_rpc_server* rpcs, rpc_ptr src_buf, size_t src_off, size_t len, uint8_t* dst_buf);
static void rpc_get_buf(rcf_rpc_server* rpcs, rpc_ptr src_buf, size_t len, uint8_t* dst_buf);
static void rpc_get_buf_off(rcf_rpc_server* rpcs, rpc_ptr_off* src_buf, size_t len, uint8_t* dst_buf);
void rpc_create_child_process_socket(const char* method, rcf_rpc_server* pco_father, int father_s, rpc_socket_domain domain, rpc_socket_type sock_type, rcf_rpc_server** pco_child, int* child_s);
te_errno tapi_sigaction_simple(rcf_rpc_server* rpcs, rpc_signum signum, const char* handler, struct rpc_struct_sigaction* oldact);
int rpc_mcast_join(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, int if_index, tarpc_joining_method how);
int rpc_mcast_leave(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, int if_index, tarpc_joining_method how);
int rpc_mcast_source_join(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, const struct sockaddr* source_addr, int if_index, tarpc_joining_method how);
int rpc_mcast_source_leave(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, const struct sockaddr* source_addr, int if_index, tarpc_joining_method how);
int rpc_common_mcast_join(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, const struct sockaddr* source_addr, int if_index, tarpc_joining_method how);
int rpc_common_mcast_leave(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, const struct sockaddr* source_addr, int if_index, tarpc_joining_method how);
int rpc_memcmp(rcf_rpc_server* rpcs, rpc_ptr_off* s1, rpc_ptr_off* s2, size_t n);
int rpc_iomux_create_state(rcf_rpc_server* rpcs, iomux_func iomux, tarpc_iomux_state* iomux_st);
int rpc_multiple_iomux_wait(rcf_rpc_server* rpcs, int fd, iomux_func iomux, tarpc_iomux_state iomux_st, int events, int count, int duration, int exp_rc, int* number, int* last_rc, int* zero_rc);
int rpc_iomux_close_state(rcf_rpc_server* rpcs, iomux_func iomux, tarpc_iomux_state iomux_st);
int rpc_multiple_iomux(rcf_rpc_server* rpcs, int fd, iomux_func iomux, int events, int count, int duration, int exp_rc, int* number, int* last_rc, int* zero_rc);
int rpc_raw2integer(rcf_rpc_server* rpcs, uint8_t* data, size_t len);
int rpc_integer2raw(rcf_rpc_server* rpcs, uint64_t number, uint8_t* data, size_t len);
int rpc_vfork_pipe_exec(rcf_rpc_server* rpcs, bool use_exec);
static bool tapi_interface_is_mine(const char* ta, const char* interface);
te_errno tapi_set_if_mtu_smart(const char* ta, const struct if_nameindex* interface, int mtu, int* old_mtu);
typedef LIST_HEAD(te_saved_mtus, te_saved_mtu);
void tapi_saved_mtus_free(te_saved_mtus* mtus);
te_errno tapi_saved_mtus2str(te_saved_mtus* mtus, char** str);
te_errno tapi_str2saved_mtus(const char* str, te_saved_mtus* mtus);
te_errno tapi_store_saved_mtus(const char* ta, const char* name, te_saved_mtus* mtus);
bool tapi_stored_mtus_exist(const char* ta, const char* name);
te_errno tapi_retrieve_saved_mtus(const char* ta, const char* name, te_saved_mtus* mtus);
te_errno tapi_set_if_mtu_smart2(const char* ta, const char* if_name, int mtu, te_saved_mtus* backup);
te_errno tapi_set_if_mtu_smart2_rollback(te_saved_mtus* backup);
bool tapi_interface_is_vlan(rcf_rpc_server* rpcs, const struct if_nameindex* interface);
te_errno tapi_interface_vlan_count(const char* ta, const char* if_name, size_t* num);
void rpc_release_rpc_ptr(rcf_rpc_server* rpcs, rpc_ptr ptr, char* ns_string);
int rpc_remove_dir_with_files(rcf_rpc_server* rpcs, const char* path);
te_errno rpc_te_file_check_executable(rcf_rpc_server* rpcs, const char* path);

// macros

#define RPC_PATTERN_GEN
#define RPC_PATTERN_GEN_LCG
#define TAPI_READ_BUF_SIZE
#define TARPC_PAT_GEN_ARG_FMT
#define TARPC_PAT_GEN_ARG_VAL(_gen_arg)

Detailed Documentation

Typedefs

typedef struct tapi_rand_gen tapi_rand_gen

Structure describing random value generation.

typedef struct tapi_pat_sender tapi_pat_sender

Pattern sender settings

typedef struct tapi_pat_receiver tapi_pat_receiver

Pattern receiver settings

typedef struct te_saved_mtu te_saved_mtu

Structure for storing MTU values.

Global Functions

static void tapi_rand_gen_set(tapi_rand_gen* arg, int min, int max, tarpc_bool once)

Set fields of tapi_rand_gen structure.

Parameters:

arg

Pointer to tapi_rand_gen structure.

min

Minimum value.

max

Maximum value.

once

Value for once field (see description in tapi_rand_gen declaration).

void tapi_pat_sender_init(tapi_pat_sender* p)

Initialize fields of tapi_pat_sender structure.

Parameters:

p

Pointer to tapi_pat_sender structure.

void tapi_pat_receiver_init(tapi_pat_receiver* p)

Initialize fields of tapi_pat_receiver structure.

Parameters:

p

Pointer to tapi_pat_receiver structure.

bool rpc_find_func(rcf_rpc_server* rpcs, const char* func_name)

Try to search a given symbol in the current library used by a given PCO with help of tarpc_find_func().

Parameters:

rpcs

RPC server

func_name

Symbol to be searched

Returns:

Value returned by tarpc_find_func()

int rpc_vlan_get_parent(rcf_rpc_server* rpcs, const char* vlan_ifname, char* parent_ifname)

Return parent network interface name of vlan interface.

Parameters:

rpcs

RPC server handle

vlan_ifname

VLAN interface name

parent_ifname

Pointer to the parent network interface name with at least IF_NAMESIZE bytes size.

Returns:

0 on success or -1 in the case of failure

int rpc_bond_get_slaves(rcf_rpc_server* rpcs, const char* bond_ifname, tqh_strings* slaves, int* slaves_num)

Return slaves network interfaces names of a bond interface.

Parameters:

rpcs

RPC server handle

bond_ifname

Bond interface name

slaves

Where to save list of slaves names

slaves_num

Where to save number of interfaces in slaves (may be NULL)

Returns:

0 on success or -1 in case of failure

tarpc_ssize_t rpc_get_sizeof(rcf_rpc_server* rpcs, const char* type_name)

Get host value of sizeof(type_name).

Parameters:

rpcs

RPC server

type_name

Name of the type

Returns:

Size of the type or -1 if such a type does not exist.

bool rpc_protocol_info_cmp(rcf_rpc_server* rpcs, const uint8_t* buf1, const uint8_t* buf2, tarpc_bool is_wide1, tarpc_bool is_wide2)

Compare protocol information (WSAPROTOCOL_INFO)

Parameters:

rpcs

RPC server

buf1

buffer containing protocol info to compare

buf2

buffer containing protocol info to compare

is_wide1

boolean defining if fields of first protocol info are wide-character

is_wide2

boolean defining if fields of second protocol info are wide-character

Returns:

true if information in buf1 is equal to information in buf2

rpc_ptr rpc_get_addrof(rcf_rpc_server* rpcs, const char* name)

Get address of the variable known on RPC server.

Parameters:

rpcs

RPC server

name

variable name

Returns:

RPC address pointer or NULL is variable is not found

uint64_t rpc_get_var(rcf_rpc_server* rpcs, const char* name, tarpc_size_t size)

Get value of the integer variable.

Routine jumps to failure is the variable is not found or incorrect parameters are provided

Parameters:

rpcs

RPC server

name

variable name

size

variable size (1, 2, 4, 8)

Returns:

variable value

void rpc_set_var(rcf_rpc_server* rpcs, const char* name, tarpc_size_t size, uint64_t val)

Change value of the integer variable.

Routine jumps to failure is the variable is not found or incorrect parameters are provided

Parameters:

rpcs

RPC server

name

variable name

size

variable size (1, 2, 4, 8)

val

variable value

int rpc_simple_sender(rcf_rpc_server* handle, int s, int size_min, int size_max, int size_rnd_once, int delay_min, int delay_max, int delay_rnd_once, int time2run, uint64_t* sent, int ignore_err)

Simple sender.

Parameters:

handle

RPC server

s

a socket to be user for sending

size_min

minimum size of the message in bytes

size_max

maximum size of the message in bytes

size_rnd_once

if true, random size should be calculated only once and used for all messages; if false, random size is calculated for each message

delay_min

minimum delay between messages in microseconds

delay_max

maximum delay between messages in microseconds

delay_rnd_once

if true, random delay should be calculated only once and used for all messages; if false, random delay is calculated for each message

time2run

how long run (in seconds)

sent

location for number of sent bytes

ignore_err

Ignore errors while run

Returns:

Number of sent bytes or -1 in the case of failure if ignore_err set to false or number of sent bytes or 0 if ignore_err set to true

int rpc_simple_receiver(rcf_rpc_server* handle, int s, uint32_t time2run, uint64_t* received)

Simple receiver.

Parameters:

handle

RPC server

s

a socket to be user for receiving

time2run

how long run (in seconds)

received

location for number of received bytes

Returns:

number of received bytes or -1 in the case of failure

int rpc_pattern_sender(rcf_rpc_server* rpcs, int s, tapi_pat_sender* args)

Patterned data sender. Data may be sent using IO multiplexing or not, according to iomux argument, with non-blocking send() or blocking, respectively.

In case of blocking send() no timeout is used. If there is any problems (e.g. ERPCTIMEOUT error), you should set the SO_SNDTIMEO via setsockopt() like it is implemented in rpc_pattern_receiver.

Parameters:

rpcs

RPC server.

s

A socket to be used for sending.

args

Pointer to tapi_pat_sender structure.

0

on success

-1

in the case of failure

Returns:

Status code.

int rpc_pattern_receiver(rcf_rpc_server* rpcs, int s, tapi_pat_receiver* args)

Patterned data receiver. Data may be received using IO multiplexing or not, according to iomux argument, with non-blocking recv() or blocking, respectively.

In case of blocking recv() the function sets SO_RCVTIMEO option several times and restores it to original value at the end.

Parameters:

rpcs

RPC server.

s

Socket descriptor.

args

Pointer to tapi_pat_receiver structure.

>=

0 number of received bytes

-2

data doesn’t match the pattern

-1

in the case of another failure

Returns:

Status code.

int rpc_wait_readable(rcf_rpc_server* rpcs, int s, uint32_t timeout)

Wait for readable socket.

Parameters:

rpcs

RPC server

s

a socket to be user for select

timeout

Receive timeout (in milliseconds)

Returns:

result of select() call

int rpc_recv_verify(rcf_rpc_server* handle, int s, const char* gen_data_fname, uint64_t start)

Receive and verify all acceptable data on socket. Verification made by function, which name is passed. This function should generate block of data by start sequence number (which is passed) and length. Then received and generated buffers are compared. Socket method recv(…, MSG_DONTWAIT) used.

Parameters:

handle

RPC server

s

a socket to be user for receiving

gen_data_fname

name of function to generate data

start

sequence number of first byte will be received.

Returns:

number of received bytes, -1 if system error, -2 if data not match.

int rpc_iomux_flooder(rcf_rpc_server* handle, int* sndrs, int sndnum, int* rcvrs, int rcvnum, int bulkszs, int time2run, int time2wait, int iomux, uint64_t* tx_stat, uint64_t* rx_stat)

Routine which receives data from specified set of sockets and sends data to specified set of sockets with maximum speed using I/O multiplexing.

Parameters:

handle

RPC server

rcvrs

set of receiver sockets

rcvnum

number of receiver sockets

sndrs

set of sender sockets

sndnum

number of sender sockets

bulkszs

sizes of data bulks to send for each sender (in bytes, 1024 bytes maximum)

time2run

how long send data (in seconds)

time2wait

how long wait data (in seconds)

iomux

type of I/O Multiplexing function (select(), pselect(), poll())

tx_stat

Tx statistics for set of sender socket to be updated (IN/OUT)

rx_stat

Rx statistics for set of receiver socket to be updated (IN/OUT)

Returns:

number of sent bytes or -1 in the case of failure

int rpc_send_flooder_iomux(rcf_rpc_server* rpcs, int sock, iomux_func iomux, tarpc_send_function send_func, bool msg_dontwait, int packet_size, int duration, uint64_t* packets, uint32_t* errors)

Send packets during a period of time, call an iomux to check OUT event if send operation is failed.

Parameters:

rpcs

RPC server handle.

sock

Socket.

iomux

Multiplexer function.

send_func

Transmitting function.

msg_dontwait

Use flag MSG_DONTWAIT.

packet_size

Payload size to be sent by a single call, bytes.

duration

How long transmit datagrams, milliseconds.

packets

Sent packets (datagrams) number.

errors

EAGAIN errors counter.

Returns:

0 on success or -1 in the case of failure.

int rpc_iomux_echoer(rcf_rpc_server* handle, int* sockets, int socknum, int time2run, int iomux, uint64_t* tx_stat, uint64_t* rx_stat)

Routine which receives data from specified set of sockets using I/O multiplexing and sends them back to the socket.

Parameters:

handle

RPC server

sockets

Set of sockets to be processed

socknum

number of sockets to be processed

time2run

how long send data (in seconds)

iomux

type of I/O Multiplexing function (select(), pselect(), poll())

tx_stat

Tx statistics for set of sender socket to be updated (IN/OUT)

rx_stat

Rx statistics for set of receiver socket to be updated (IN/OUT)

Returns:

0 on success or -1 in the case of failure

int rpc_iomux_splice(rcf_rpc_server* rpcs, int iomux, int fd_in, int fd_out, size_t len, int flags, int time2run)

Routine which calls I/O multiplexing function and then calls splice.

Parameters:

rpcs

RPC server

iomux

type of I/O Multiplexing function (select(), pselect(), poll())

fd_in

file descriptor opened for writing

fd_out

file descriptor opened for reading

len

‘len’ parameter for splice() call

flags

flags for splice() call

time2run

Duration of the call

Returns:

number of sent bytes or -1 in the case of failure

ssize_t rpc_socket_to_file(rcf_rpc_server* handle, int sock, const char* path_name, long timeout)

Routine which receives data from opened socket descriptor and write its to the file. Processing is finished when timeout expired.

Parameters:

handle

RPC server

sock

socket descriptor for data receiving

path_name

path name where write received data

timeout

timeout to finish processing

Returns:

Number of processed bytes or -1 in the case of failure

int64_t rpc_copy_fd2fd(rcf_rpc_server* rpcs, int out_fd, int in_fd, int timeout, uint64_t count)

Copy data between one file descriptor and another. If in_fd is a file which supports mmap(2)-like operations then it is recommended to use rpc_sendfile cause it is more efficient.

Parameters:

rpcs

RPC server handle.

out_fd

File descriptor opened for writing. Can be a socket.

in_fd

File descriptor opened for reading. Can be a socket.

timeout

Number of milliseconds that function should block waiting for in_fd to become ready to read the next portion of data while all requested data will not be read.

count

Number of bytes to copy between the file descriptors. If 0 then all available data should be copied, i.e. while EOF will not be gotten.

Returns:

If the transfer was successful, the number of copied bytes is returned. On error, -1 is returned, and errno is set appropriately.

int rpc_ftp_open(rcf_rpc_server* handle, char* uri, bool rdonly, bool passive, int offset, int* sock)

Open FTP connection for reading/writing the file. Control connection should be closed via ftp_close.

Parameters:

handle

RPC server

uri

FTP uri: ftp://user:password@server/directory/file

rdonly

if true, get file

passive

if true, passive mode

offset

file offset

sock

pointer to a socket descriptor

Returns:

File descriptor, which may be used for reading/writing data

int rpc_ftp_close(rcf_rpc_server* handle, int sock)

Close FTP control connection.

Parameters:

handle

RPC server

sock

control socket descriptor

Returns:

0 on success or -1 on failure

int rpc_overfill_buffers_data(rcf_rpc_server* rpcs, int sock, uint64_t* sent, iomux_func iomux, uint8_t** sent_data)

Overfill the buffers on receive and send sides of TCP connection. On Windows, this call excepts socket to be in blocking mode. To use it on non-blocking sockets refer to rpc_overfill_buffers_ex.

Parameters:

rpcs

RPC server

sock

socket for sending

sent

total bytes written to sending socket while both sending and receiving side buffers are overfilled.

iomux

IOMUX function to use when checking for socket writeability.

sent_data

If not NULL, pointer to sent data will be retrieved here (it should be freed by the caller).

Returns:

-1 in the case of failure or 0 on success

int rpc_drain_fd(rcf_rpc_server* rpcs, int fd, size_t size, int time2wait, uint64_t* read)

Drain all data on a fd.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

size

Read buffer size, bytes.

time2wait

How long wait for data after read failure, milliseconds. If a negative value is set, then blocking recv() will be used to read data.

read

Pointer for read data amount or NULL.

Returns:

The last return code of recv() function: -1 in the case of failure or 0 on success. In a common case -1 with RPC_EAGAIN should be considered as the correct behavior if the connection was not closed from the peer side.

int rpc_drain_fd_duration(rcf_rpc_server* rpcs, int fd, size_t size, int time2wait, unsigned int duration, uint64_t* read)

The same as rpc_drain_fd() but allows to specify general time limit for this call.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

size

Read buffer size, bytes.

time2wait

How long to wait for data after read failure, milliseconds. If a negative value is set and duration is zero, then blocking recv() will be used to read data. Otherwise, if value is negative or zero, new data will be waited for until duration timeout expires with an iomux function.

duration

If not zero, specifies time limit for this call, in seconds.

read

Pointer for read data amount or NULL.

Returns:

The last return code of recv() function: -1 in the case of failure or 0 on success. In a common case -1 with RPC_EAGAIN should be considered as the correct behavior if the connection was not closed from the peer side.

int rpc_drain_fd_simple(rcf_rpc_server* rpcs, int fd, uint64_t* read)

Simplified call of rpc_drain_fd(). It executes the call with default size and time2wait parameters what is useful in a common case. Also it checks return code and errno.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

read

Pointer for read data amount or NULL.

Returns:

The last return code of recv() function. Actually it can be -1 with RPC_EAGAIN or 0, otherwise the functions reports a verdict and jumps to cleanup. Zero return code indicates that the connection was closed from the peer side.

int rpc_overfill_fd(rcf_rpc_server* rpcs, int write_end, uint64_t* sent)

Overfill the buffers of the pipe.

Parameters:

rpcs

RPC server

write_end

Write end of the pipe

sent

total bytes written to the pipe

Returns:

-1 in the case of failure or 0 on success

int rpc_read_fd2te_dbuf_append(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_dbuf* dbuf)

Read all data on an fd and append it to dbuf.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

time2wait

Time to wait for data, milliseconds. Negative value means an infinite timeout and it is a user responsibility to care about RPC timeout in this case.

amount

Number of bytes to read, if 0 then only time2wait limits it.

dbuf

Buffer to append read data to.

Returns:

-1 in the case of failure or 0 on success (timeout is expired, amount bytes is read, EOF is got).

int rpc_read_fd2te_dbuf(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_dbuf* dbuf)

Read all data from fd to dbuf.

The function resets dbuf.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

time2wait

Time to wait for data, milliseconds. Negative value means an infinite timeout and it is a user responsibility to care about RPC timeout in this case.

amount

Number of bytes to read, if 0 then only time2wait limits it.

dbuf

Buffer to put read data to.

Returns:

-1 in the case of failure or 0 on success (timeout is expired, amount bytes is read, EOF is got).

int rpc_read_fd(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, void** buf, size_t* read)

Read all data on an fd.

buf should be freed with free(3) when it is no longer needed, independently on result.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

time2wait

Time to wait for data, milliseconds. Negative value means an infinite timeout and it is a user responsibility to care about RPC timeout in this case.

amount

Number of bytes to read, if 0 then only time2wait limits it.

buf

Pointer to buffer (it is allocated by the function).

read

Number of read bytes.

Returns:

-1 in the case of failure or 0 on success (timeout is expired, amount bytes is read, EOF is got).

int rpc_read_fd2te_string_append(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_string* testr)

Read all string data on an fd and append it to testr.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

time2wait

Time to wait for data, milliseconds. Negative value means an infinite timeout and it is a user responsibility to care about RPC timeout in this case.

amount

Number of bytes to read, if 0 then only time2wait limits it.

testr

Buffer to append read data to.

Returns:

-1 in the case of failure or 0 on success (timeout is expired, amount bytes is read, EOF is got).

int rpc_read_fd2te_string(rcf_rpc_server* rpcs, int fd, int time2wait, size_t amount, te_string* testr)

Read all string data from fd to testr.

The function resets testr.

Parameters:

rpcs

RPC server handle.

fd

File descriptor or socket.

time2wait

Time to wait for data, milliseconds. Negative value means an infinite timeout and it is a user responsibility to care about RPC timeout in this case.

amount

Number of bytes to read, if 0 then only time2wait limits it.

testr

Buffer to put read data to.

Returns:

-1 in the case of failure or 0 on success (timeout is expired, amount bytes is read, EOF is got).

void rpc_vm_trasher(rcf_rpc_server* rpcs, bool start)

VM trasher to keep memory pressure on the host where the specified RPC server runs.

Parameters:

rpcs

RPC server

start

true if want to start the VM trasher, false if want to stop the VM trasher.

void rpc_set_buf_gen(rcf_rpc_server* rpcs, const uint8_t* src_buf, size_t len, rpc_ptr dst_buf, size_t dst_off)

Copy the src_buf buffer in dst_buf located in TA address space

Parameters:

rpcs

RPC server handle

src_buf

pointer to the source buffer

len

length of data to be copied

dst_buf

pointer to the destination buffer

dst_off

displacement in the destination buffer

void rpc_set_buf_pattern_gen(rcf_rpc_server* rpcs, int pattern, size_t len, rpc_ptr dst_buf, size_t dst_off)

Fill dst_buf located in TA address space by specified pattern

Parameters:

rpcs

RPC server handle

pattern

pattern to be used for buffer filling (TAPI_RPC_BUF_RAND if the buffer should be filled by random data)

len

length of data to be copied

dst_buf

pointer to the destination buffer

dst_off

displacement in the destination buffer

void rpc_get_buf_gen(rcf_rpc_server* rpcs, rpc_ptr src_buf, size_t src_off, size_t len, uint8_t* dst_buf)

Copy the src_buf buffer located in TA address space to the dst_buf buffer.

Parameters:

rpcs

RPC server handle

src_buf

source buffer

src_off

displacement in the source buffer

len

length of data to be copied

dst_buf

destination buffer

void rpc_create_child_process_socket(const char* method, rcf_rpc_server* pco_father, int father_s, rpc_socket_domain domain, rpc_socket_type sock_type, rcf_rpc_server** pco_child, int* child_s)

Create a child process (with a duplicated socket in case of winsock2).

Parameters:

method

“inherit”, “DuplicateSocket” or “DuplicateHandle”

pco_father

RPC server handle

father_s

socket on pco_father

domain

domain, used in test

sock_type

type of socket, used in test

pco_child

new process

child_s

duplicated socket on pco_child

te_errno tapi_sigaction_simple(rcf_rpc_server* rpcs, rpc_signum signum, const char* handler, struct rpc_struct_sigaction* oldact)

Wrapper for rpc_sigaction() function to install ‘sa_sigaction’ with blocking of all signals and SA_RESTART flag.

Parameters:

rpcs

RPC server handle

signum

Signal number

handler

Signal handler ‘sa_sigaction’

oldact

Pointer to previously associated with the signal action or NULL

Returns:

Status code.

int rpc_mcast_join(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, int if_index, tarpc_joining_method how)

Join a multicasting group on specified interface.

Parameters:

rpcs

RPC server handle

s

socket descriptor

mcast_addr

multicast address (IPv4 or IPv6).

if_index

interface index

how

joining method:

  • TARPC_MCAST_ADD_DROP sockopt IP_ADD/DROP_MEMBERSHIP

  • TARPC_MCAST_JOIN_LEAVE sockopt MCAST_JOIN/LEAVE_GROUP

  • TARPC_MCAST_WSA WSAJoinLeaf(), no leave

Returns:

0 on success, -1 on failure

int rpc_mcast_leave(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, int if_index, tarpc_joining_method how)

Leave a multicasting group.

Parameters are same as above.

int rpc_mcast_source_join(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, const struct sockaddr* source_addr, int if_index, tarpc_joining_method how)

Join a multicasting group with source on specified interface.

Parameters:

rpcs

RPC server handle

s

socket descriptor

mcast_addr

multicast address

source_addr

source address

if_index

interface index

how

joining method:

  • TARPC_MCAST_SOURCE_ADD_DROP sockopt IP_ADD/DROP_SOURCE_MEMBERSHIP

  • TARPC_MCAST_SOURCE_JOIN_LEAVE sockopt MCAST_JOIN/LEAVE_SOURCE_GROUP

Returns:

0 on success, -1 on failure

int rpc_mcast_source_leave(rcf_rpc_server* rpcs, int s, const struct sockaddr* mcast_addr, const struct sockaddr* source_addr, int if_index, tarpc_joining_method how)

Leave a multicasting group with source.

Parameters are same as above.

int rpc_memcmp(rcf_rpc_server* rpcs, rpc_ptr_off* s1, rpc_ptr_off* s2, size_t n)

Compare memory areas

See memcmp(3)

Parameters:

rpcs

RPC server handle

s1

RPC pointer to the first memory area

s2

RPC pointer to the second memory area

n

Size of memory areas to be compared

Returns:

An integer less than, equal to, or greater than zero if the first n bytes of s1 is found, respectively, to be less than, to match, or be greater than the first n bytes of s2.

int rpc_iomux_create_state(rcf_rpc_server* rpcs, iomux_func iomux, tarpc_iomux_state* iomux_st)

Initialize iomux_state with zero value

Caller must free memory allocated for iomux_st using rpc_iomux_close()

Parameters:

rpcs

RPC server handle

iomux

Multiplexer function type

iomux_st

The multiplexer context pointer

Returns:

0 on success or -1 in the case of failure.

int rpc_multiple_iomux_wait(rcf_rpc_server* rpcs, int fd, iomux_func iomux, tarpc_iomux_state iomux_st, int events, int count, int duration, int exp_rc, int* number, int* last_rc, int* zero_rc)

Call I/O multiplexing wait function multiple times

Parameters:

rpcs

RPC server handle

fd

File descriptor

iomux

Iomux to be called

iomux_st

The multiplexer context pointer

events

poll() events to be checked for

count

How many times to call a function or -1 for unlimited

duration

Call iomux during a specified time in milliseconds or -1

exp_rc

Expected return value

number

If not NULL, will be set to the number of iomux calls before timeout occurred or an error was returned.

last_rc

If not NULL, will be set to the last return value of an iomux function.

zero_rc

If not NULL, number of zero code returned by iomux

Returns:

0 on success or -1 in the case of failure.

int rpc_iomux_close_state(rcf_rpc_server* rpcs, iomux_func iomux, tarpc_iomux_state iomux_st)

Close iomux state when necessary

Parameters:

rpcs

RPC server handle

iomux

Multiplexer function type

iomux_st

The multiplexer context pointer

Returns:

0 on success or -1 in the case of failure.

int rpc_multiple_iomux(rcf_rpc_server* rpcs, int fd, iomux_func iomux, int events, int count, int duration, int exp_rc, int* number, int* last_rc, int* zero_rc)

Call I/O multiplexing function multiple times.

Parameters:

rpcs

RPC server handle

fd

File descriptor

iomux

Iomux to be called

events

poll() events to be checked for

count

How many times to call a function or -1 for unlimited

duration

Call iomux during a specified time in milliseconds or -1

exp_rc

Expected return value

number

If not NULL, will be set to the number of iomux calls before timeout occurred or an error was returned.

last_rc

If not NULL, will be set to the last return value of an iomux function.

zero_rc

If not NULL, number of zero code returned by iomux

int rpc_raw2integer(rcf_rpc_server* rpcs, uint8_t* data, size_t len)

Convert raw data to integer (this is useful when raw data was obtained from a test machine with different endianness).

Parameters:

rpcs

RPC server

data

Data to be converted

len

Length of data to be converted

Returns:

0 on success or -1

int rpc_integer2raw(rcf_rpc_server* rpcs, uint64_t number, uint8_t* data, size_t len)

Convert integer value to raw representation (this is useful when raw data is to be processed by a test machine with different endianness).

Parameters:

rpcs

RPC server

number

Number to be converted

data

Buffer where to place converted value

len

Integer type size

Returns:

0 on success or -1

int rpc_vfork_pipe_exec(rcf_rpc_server* rpcs, bool use_exec)

Specioal function for sockapi-ts/basic/vfork_check_hang test.

Parameters:

rpcs

RPC server

use_exec

Use execve() or _exit() function

Returns:

0 on success or -1

static bool tapi_interface_is_mine(const char* ta, const char* interface)

Determine if the interface is grabbed by the testing.

Parameters:

ta

Test agent name

interface

Interface name

Returns:

true if the interface is grabbed.

te_errno tapi_set_if_mtu_smart(const char* ta, const struct if_nameindex* interface, int mtu, int* old_mtu)

Set new MTU value for a given interface (increasing MTU for the interfaces it is based on if necessary).

This function does not save previous values of MTU for affected “ancestor” interfaces; you should rely on Configurator to restore them. Still it makes sense to restore MTU for the interface passed to this function, as otherwise Configurator may be not able to restore MTU values for its “descendant” interfaces, which may change as a side effect if we descrease MTU. Function tapi_set_if_mtu_smart2() can be used to change MTU saving old values for all related interfaces, then the changes can be rolled back using function tapi_set_if_mtu_smart2_rollback().

Parameters:

ta

Test agent name

interface

Network interface

mtu

MTU value

old_mtu

If not NULL, previous value of MTU for the interface will be saved.

Returns:

Status code.

typedef LIST_HEAD(te_saved_mtus, te_saved_mtu)

Type of list of MTU values.

void tapi_saved_mtus_free(te_saved_mtus* mtus)

Free memory allocated for items of a list of MTU values.

Parameters:

mtus

Pointer to the list.

te_errno tapi_saved_mtus2str(te_saved_mtus* mtus, char** str)

Convert list of saved MTU values to string.

Parameters:

mtus

List of saved MTU values.

str

Where to save pointer to the string (memory is allocated by this function).

Returns:

Status code.

te_errno tapi_str2saved_mtus(const char* str, te_saved_mtus* mtus)

Convert string to list of saved MTU values.

Parameters:

str

String to convert.

mtus

Pointer to list head.

Returns:

Status code.

te_errno tapi_store_saved_mtus(const char* ta, const char* name, te_saved_mtus* mtus)

Save MTU values to a temporary local file.

List of MTU values will be empty after calling this function. Register “saved_mtus” node under “/local” in Configuration tree to use this function.

Parameters:

ta

Test Agent name.

name

Unique name.

mtus

List of MTU values.

Returns:

Status code.

bool tapi_stored_mtus_exist(const char* ta, const char* name)

Check whether MTU values are already stored under a given name.

Parameters:

ta

Test Agent name.

name

Name used to identify MTU values list.

Returns:

true if MTU values are stored under the name, false otherwise.

te_errno tapi_retrieve_saved_mtus(const char* ta, const char* name, te_saved_mtus* mtus)

Retrieve saved MTU values from a temporary local file.

This function may be called only once for a given name, as the file fill be removed as a result.

Parameters:

ta

Test Agent name.

name

Unique name previously passed to tapi_store_save_mtus().

mtus

MTU values.

Returns:

Status code.

te_errno tapi_set_if_mtu_smart2(const char* ta, const char* if_name, int mtu, te_saved_mtus* backup)

Set new MTU value for a given interface (increasing MTU for the interfaces it is based on if necessary), previously saving MTU of all related interfaces.

The same backup argument may be passed to several calls of this function; in that case all changes made by them can be reverted with a single call of tapi_set_if_mtu_smart2_rollback().

Parameters:

ta

Test agent name

if_name

Network interface name

mtu

MTU value

backup

If not NULL, original values of MTU for all affected interfaces will be saved here.

Returns:

Status code.

te_errno tapi_set_if_mtu_smart2_rollback(te_saved_mtus* backup)

Revert changes made by tapi_set_if_mtu_smart2().

Parameters:

backup

Where the original MTU values are saved.

Returns:

Status code.

bool tapi_interface_is_vlan(rcf_rpc_server* rpcs, const struct if_nameindex* interface)

Check if the interface is VLAN interface.

There could be some interfaces like ipvlan, macvlan, bond and etc. over vlan, and this function theoretically should work for such combinations, but it was tested only for macvlan over vlan.

Parameters:

rpcs

RPC server handler

interface

Interface name

Returns:

true if the interface is grabbed.

te_errno tapi_interface_vlan_count(const char* ta, const char* if_name, size_t* num)

Compute number of VLAN interfaces on which the interface is based (including the interface itself). This should be the number of VLAN tags in Ethernet frames going via this interface.

Parameters:

ta

Test agent name

if_name

Interface name

num

Number of VLAN “ancestor” interfaces, including this interface itself if it is VLAN

Returns:

Status code.

void rpc_release_rpc_ptr(rcf_rpc_server* rpcs, rpc_ptr ptr, char* ns_string)

Release the RPC pointer with specified namespace without any system call

Parameters:

rpcs

RPC server handle

ptr

RPC pointer

ns_string

Namespace as string for ptr

int rpc_remove_dir_with_files(rcf_rpc_server* rpcs, const char* path)

Remove a directory with all files.

Parameters:

rpcs

RPC server

path

Path of the directory to be removed

Returns:

-1 in the case of failure or 0 on success

te_errno rpc_te_file_check_executable(rcf_rpc_server* rpcs, const char* path)

Check that the file is executable.

If path doesn’t start with / or ``./ or ``../ then path is searched in directories from the remote PATH. Otherwise, only the path itself is checked.

Parameters:

rpcs

RPC server handle

path

path to the file

Returns:

Status code.

See also:

te_file_check_executable()

Macros

#define RPC_PATTERN_GEN

Fill buffer with a sequence of concatenated numbers 1, 2, 3, … using get_nth_elm() function.

#define RPC_PATTERN_GEN_LCG

Fills the buffer with a linear congruential sequence and updates arg parameter for the next call.

Each element is calculated using the formula: X[n] = a * X[n-1] + c, where a and c are taken from arg parameter:

  • a is arg->coef2,

  • c is arg->coef3

See https://en.wikipedia.org/wiki/Linear_congruential_generator for details.

Parameters:

buf

Buffer

size

Buffer size in bytes

arg

Pointer to tarpc_pat_gen_arg structure, where

  • coef1 is x0 - starting number in a sequence,

  • coef2 is a - multiplying constant,

  • coef3 is c - additive constant

Returns:

0 on success

#define TAPI_READ_BUF_SIZE

Default read buffer size.

#define TARPC_PAT_GEN_ARG_FMT

Macro for logging the tarpc_pat_gen_arg structure members. Using with TARPC_PAT_GEN_ARG_VAL.

Example:

tarpc_pat_gen_arg pattern_gen_args = {1,2,3,4};
RING("pattern generator coeffs are "TARPC_PAT_GEN_ARG_FMT,
     TARPC_PAT_GEN_ARG_VAL(pattern_gen_args));
#define TARPC_PAT_GEN_ARG_VAL(_gen_arg)

Macro for logging the tarpc_pat_gen_arg structure members. Using with TARPC_PAT_GEN_ARG_FMT.

Example:

tarpc_pat_gen_arg pattern_gen_args = {1,2,3,4};
RING("pattern generator coeffs are "TARPC_PAT_GEN_ARG_FMT,
     TARPC_PAT_GEN_ARG_VAL(pattern_gen_args));