From af24aa5bf2ae888bad7e72543e07ee19935b21cc Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 7 Jul 2023 22:36:17 -0500 Subject: [PATCH] Update: Socket bind functions, socket address family enumeration, and rename max_backlog. Change the f_socket_bind_local() bind function to not call memset() and use the new address structure. Add f_socket_bind_inet4() and f_socket_bind_inet6() bind functions in a similar way to f_socket_bind_local(). Update the appropriate documentation. Add the appropriate unit tests. The name max_backlog for f_socket_listen() is better named backlog_max as per the FLL style practices. --- level_0/f_socket/c/socket.c | 89 ++++++++++++++---- level_0/f_socket/c/socket.h | 97 +++++++++++++++++--- level_0/f_socket/c/socket/common.h | 76 +++++++-------- level_0/f_socket/data/build/settings-tests | 2 +- .../f_socket/tests/unit/c/test-socket-bind_inet4.c | 102 +++++++++++++++++++++ .../f_socket/tests/unit/c/test-socket-bind_inet4.h | 34 +++++++ .../f_socket/tests/unit/c/test-socket-bind_inet6.c | 102 +++++++++++++++++++++ .../f_socket/tests/unit/c/test-socket-bind_inet6.h | 34 +++++++ .../f_socket/tests/unit/c/test-socket-bind_local.c | 3 - level_0/f_socket/tests/unit/c/test-socket.c | 8 ++ level_0/f_socket/tests/unit/c/test-socket.h | 2 + 11 files changed, 477 insertions(+), 72 deletions(-) create mode 100644 level_0/f_socket/tests/unit/c/test-socket-bind_inet4.c create mode 100644 level_0/f_socket/tests/unit/c/test-socket-bind_inet4.h create mode 100644 level_0/f_socket/tests/unit/c/test-socket-bind_inet6.c create mode 100644 level_0/f_socket/tests/unit/c/test-socket-bind_inet6.h diff --git a/level_0/f_socket/c/socket.c b/level_0/f_socket/c/socket.c index 209556c..1d9ece3 100644 --- a/level_0/f_socket/c/socket.c +++ b/level_0/f_socket/c/socket.c @@ -72,6 +72,68 @@ extern "C" { } #endif // _di_f_socket_bind_ +#ifndef _di_f_socket_bind_inet4_ + f_status_t f_socket_bind_inet4(f_socket_t * const socket) { + #ifndef _di_level_0_parameter_checking_ + if (!socket) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (socket->domain != f_socket_protocol_family_inet4_e) return F_status_set_error(F_address_not); + + socket->address.inet4.sin_family = f_socket_address_family_inet4_e; + socket->length = sizeof(struct sockaddr_in); + + if (bind(socket->id, (struct sockaddr *) &socket->address.inet4, socket->length) == -1) { + if (errno == EACCES) return F_status_set_error(F_access_denied); + if (errno == EADDRINUSE) return F_status_set_error(F_busy_address); + if (errno == EADDRNOTAVAIL) return F_status_set_error(F_available_not_address); + if (errno == EFAULT) return F_status_set_error(F_buffer); + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == ELOOP) return F_status_set_error(F_loop); + if (errno == ENAMETOOLONG) return F_status_set_error(F_string_too_large); + if (errno == ENOENT) return F_status_set_error(F_file_found_not); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + if (errno == ENOTDIR) return F_status_set_error(F_directory_found_not); + if (errno == ENOTSOCK) return F_status_set_error(F_socket_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_socket_bind_inet4_ + +#ifndef _di_f_socket_bind_inet6_ + f_status_t f_socket_bind_inet6(f_socket_t * const socket) { + #ifndef _di_level_0_parameter_checking_ + if (!socket) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (socket->domain != f_socket_protocol_family_inet6_e) return F_status_set_error(F_address_not); + + socket->address.inet6.sin6_family = f_socket_address_family_inet6_e; + socket->length = sizeof(struct sockaddr_in6); + + if (bind(socket->id, (struct sockaddr *) &socket->address.inet6, socket->length) == -1) { + if (errno == EACCES) return F_status_set_error(F_access_denied); + if (errno == EADDRINUSE) return F_status_set_error(F_busy_address); + if (errno == EADDRNOTAVAIL) return F_status_set_error(F_available_not_address); + if (errno == EFAULT) return F_status_set_error(F_buffer); + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == ELOOP) return F_status_set_error(F_loop); + if (errno == ENAMETOOLONG) return F_status_set_error(F_string_too_large); + if (errno == ENOENT) return F_status_set_error(F_file_found_not); + if (errno == ENOMEM) return F_status_set_error(F_memory_not); + if (errno == ENOTDIR) return F_status_set_error(F_directory_found_not); + if (errno == ENOTSOCK) return F_status_set_error(F_socket_not); + + return F_status_set_error(F_failure); + } + + return F_none; + } +#endif // _di_f_socket_bind_inet6_ + #ifndef _di_f_socket_bind_local_ f_status_t f_socket_bind_local(f_socket_t * const socket) { #ifndef _di_level_0_parameter_checking_ @@ -80,23 +142,18 @@ extern "C" { if (socket->domain != f_socket_protocol_family_local_e) return F_status_set_error(F_local_not); - memset((void *) &socket->address, 0, sizeof(struct sockaddr_un)); + socket->address.local.sun_family = f_socket_address_family_local_e; + socket->length = sizeof(struct sockaddr_un); - { - struct sockaddr_un *address = (struct sockaddr_un *) &socket->address; - - address->sun_family = f_socket_address_family_local_e; - - if (socket->name.used && socket->name.string) { - strncpy(address->sun_path, socket->name.string, socket->name.used); - address->sun_path[socket->name.used] = 0; - } - else { - address->sun_path[0] = 0; - } + if (socket->name.used && socket->name.string) { + memcpy((void *) socket->address.local.sun_path, (void *) socket->name.string, socket->name.used); + socket->address.local.sun_path[socket->name.used] = 0; + } + else { + socket->address.local.sun_path[0] = 0; } - if (bind(socket->id, (struct sockaddr *) &socket->address, sizeof(struct sockaddr_un)) == -1) { + if (bind(socket->id, (struct sockaddr *) &socket->address.local, socket->length) == -1) { if (errno == EACCES) return F_status_set_error(F_access_denied); if (errno == EADDRINUSE) return F_status_set_error(F_busy_address); if (errno == EADDRNOTAVAIL) return F_status_set_error(F_available_not_address); @@ -254,12 +311,12 @@ extern "C" { #endif // _di_f_socket_disconnect_ #ifndef _di_f_socket_listen_ - f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int max_backlog) { + f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int backlog_max) { #ifndef _di_level_0_parameter_checking_ if (!socket) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (listen(socket->id, max_backlog) == -1) { + if (listen(socket->id, backlog_max) == -1) { if (errno == EADDRINUSE) return F_status_set_error(F_busy_address); if (errno == EBADF) return F_status_set_error(F_file_descriptor); if (errno == ENOTSOCK) return F_status_set_error(F_socket_not); diff --git a/level_0/f_socket/c/socket.h b/level_0/f_socket/c/socket.h index f017d29..9ff3dc3 100644 --- a/level_0/f_socket/c/socket.h +++ b/level_0/f_socket/c/socket.h @@ -103,13 +103,12 @@ extern "C" { /** * Bind a socket to a name. * - * This does not initialize or otherwise memset() the address. - * * @param socket * The socket structure. - * The socket.address may point to any valid structure, like "struct sockaddr", "struct sockaddr_un", or "struct sockaddr_in". + * The socket.address may be any valid structure, like "struct sockaddr", "struct sockaddr_un", or "struct sockaddr_in". + * The socket.address.*.*_family is not directly altered by this function. * The caller must appropriately initialize and configure the socket.address. - * The socket.length must represent the full size of the address structure. + * The socket.length must represent the full size of the address structure and is not altered by this function. * The socket.id must refer to a valid socket file descriptor. * * @return @@ -136,16 +135,87 @@ extern "C" { #endif // _di_f_socket_bind_ /** - * Bind a socket to a local (UNIX) socket file. + * Bind a socket to an IPv4 address. + * + * @param socket + * The socket to use. + * + * The socket.address.inet4.sin_family is directly assigned to f_socket_address_family_inet4_e. + * The socket.domain (potocol family) must be assigned to f_socket_protocol_family_inet4_e. + * The socket.length is updated to represent the size of "struct sockaddr_in". + * The socket.type (address family) will be assigned to f_socket_address_family_inet4_e. + * + * @return + * F_none on success. + * + * F_address (with error bit) if address is already in use (therefore unavailable). + * F_address_not (with error bit) if socket.domain is not set to f_socket_protocol_family_inet4_e. + * F_available_not_address (with error bit) if address is unavailable (is non-existent). + * F_buffer (with error bit) if the buffer is invalid. + * F_busy_address (with error bit) if address is already in use (therefore unavailable). + * F_directory_found_not (with error bit) if directory was not found. + * F_file_found_not (with error bit) if file not found. + * F_memory_not (with error bit) if out of memory. + * F_name (with error bit) on path name error. + * F_parameter (with error bit) if a parameter is invalid. + * F_socket_not (with error bit) if the id is not a socket descriptor. + * F_string_too_large (with error bit) if string is too large to store in the buffer. + * + * F_failure (with error bit) for any other error. * - * This does initialize and memset() the address with the address set to a UNIX socket (struct sockaddr_un). + * @see bind() + */ +#ifndef _di_f_socket_bind_inet4_ + extern f_status_t f_socket_bind_inet4(f_socket_t * const socket); +#endif // _di_f_socket_bind_inet4_ + +/** + * Bind a socket to an IPv6 address. * * @param socket - * The socket structure. - * The socket.address must point to a "struct sockaddr_un". + * The socket to use. + * + * The socket.address.inet6.sin_family is directly assigned to f_socket_address_family_inet6_e. + * The socket.domain (potocol family) must be assigned to f_socket_protocol_family_inet6_e. + * The socket.length is updated to represent the size of "struct sockaddr_in6". + * The socket.type (address family) will be assigned to f_socket_address_family_inet6_e. + * + * @return + * F_none on success. + * + * F_address (with error bit) if address is already in use (therefore unavailable). + * F_address_not (with error bit) if socket.domain is not set to f_socket_protocol_family_inet6_e. + * F_available_not_address (with error bit) if address is unavailable (is non-existent). + * F_buffer (with error bit) if the buffer is invalid. + * F_busy_address (with error bit) if address is already in use (therefore unavailable). + * F_directory_found_not (with error bit) if directory was not found. + * F_file_found_not (with error bit) if file not found. + * F_memory_not (with error bit) if out of memory. + * F_name (with error bit) on path name error. + * F_parameter (with error bit) if a parameter is invalid. + * F_socket_not (with error bit) if the id is not a socket descriptor. + * F_string_too_large (with error bit) if string is too large to store in the buffer. + * + * F_failure (with error bit) for any other error. + * + * @see bind() + */ +#ifndef _di_f_socket_bind_inet6_ + extern f_status_t f_socket_bind_inet6(f_socket_t * const socket); +#endif // _di_f_socket_bind_inet6_ + +/** + * Bind a socket to a local (UNIX) socket file. + * + * @param socket + * The socket to use. + * + * The socket.address.local.sun_family is directly assigned to f_socket_address_family_local_e. + * The socket.address.local.sun_path is updated with the value from socket.name.string. * The socket.domain (potocol family) must be assigned to f_socket_protocol_family_local_e. - * The socket.type (address family) will be assigned to f_socket_address_family_local_e. + * The socket.length is updated to represent the size of "struct sockaddr_un". * The socket.name must be assigned to a path. + * The socket.type (address family) will be assigned to f_socket_address_family_local_e. * * @return * F_none on success. @@ -156,7 +226,7 @@ extern "C" { * F_busy_address (with error bit) if address is already in use (therefore unavailable). * F_directory_found_not (with error bit) if directory was not found. * F_file_found_not (with error bit) if file not found. - * F_local_not (with erro bit) if domain in not a UNIX socket. + * F_local_not (with error bit) if socket.domain is not set to f_socket_protocol_family_local_e. * F_memory_not (with error bit) if out of memory. * F_name (with error bit) on path name error. * F_parameter (with error bit) if a parameter is invalid. @@ -166,8 +236,7 @@ extern "C" { * F_failure (with error bit) for any other error. * * @see bind() - * @see memset() - * @see strncpy() + * @see memcpy() */ #ifndef _di_f_socket_bind_local_ extern f_status_t f_socket_bind_local(f_socket_t * const socket); @@ -333,7 +402,7 @@ extern "C" { * @param socket * The socket structure. * The socket.id must represent a valid socket file descriptor. - * @param max_backlog + * @param backlog_max * The max length of the pending connections queue. * Suggested default setting: 8. * @@ -350,7 +419,7 @@ extern "C" { * @see listen() */ #ifndef _di_f_socket_listen_ - extern f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int max_backlog); + extern f_status_t f_socket_listen(f_socket_t * const socket, const unsigned int backlog_max); #endif // _di_f_socket_listen_ /** diff --git a/level_0/f_socket/c/socket/common.h b/level_0/f_socket/c/socket/common.h index b1ddf5d..da8ebb6 100644 --- a/level_0/f_socket/c/socket/common.h +++ b/level_0/f_socket/c/socket/common.h @@ -37,49 +37,49 @@ extern "C" { * * f_socket_address_family_*_e: * - unspecified: No protocol family specified. - * - local: Localhost, pipes, Unix sockets, or file sockets (PF_LOCAL, PF_UNIX, PF_FILE). - * - inet: IP protocol family. - * - ax25: Amateur Radio AX.25. - * - ipx: Novell Internet Protocol. + * - alg: Algorithm sockets. * - appletalk: Appletalk DDP. - * - netrom: Amateur radio NetROM. - * - bridge: Multiprotocol bridge. + * - ash: Ash. * - atmpvc: ATM PVCs. - * - x25: Reserved for X.25 project. - * - inet6: IP version 6. - * - rose: Amateur Radio X.25 PLP. + * - atmsvc: ATM SVCs. + * - ax25: Amateur Radio AX.25. + * - bluetooth: Bluetooth sockets. + * - bridge: Multiprotocol bridge. + * - caif: CAIF sockets. + * - can: Controller Area Network. * - decnet: Reserved for DECnet project. - * - netbeui: Reserved for 802.2LLC project. - * - security: Security callback pseudo AF. - * - key: PF_KEY key management API. - * - netlink: Netlink and BSD (PF_NETLINK and PF_ROUTE). - * - packet: Packet family. - * - ash: Ash. * - econet: Acorn Econet. - * - atmsvc: ATM SVCs. - * - rds: RDS sockets. - * - sna: Linux SNA Project. + * - ib: Native InfiniBand address. + * - ieee802154: IEEE 802.15.4 sockets. + * - inet4: IP version 4. + * - inet6: IP version 6. + * - ipx: Novell Internet Protocol. * - irda: IRDA sockets. - * - pppox: PPPoX sockets. - * - wanpipe: Wanpipe API sockets. + * - isdn: mISDN sockets. + * - iucb: IUCV sockets. + * - kcm: Kernel Connection Multiplexor. + * - key: PF_KEY key management API. * - llc: Linux LLC. - * - ib: Native InfiniBand address. + * - local: Localhost, pipes, Unix sockets, or file sockets (PF_LOCAL, PF_UNIX, PF_FILE). * - mpls: MPLS. - * - can: Controller Area Network. - * - tipc: TIPC sockets. - * - bluetooth: Bluetooth sockets. - * - iucb: IUCV sockets. - * - rxrpc: RxRPC sockets. - * - isdn: mISDN sockets. - * - phonet: Phonet sockets. - * - ieee802154: IEEE 802.15.4 sockets. - * - caif: CAIF sockets. - * - alg: Algorithm sockets. + * - netbeui: Reserved for 802.2LLC project. + * - netlink: Netlink and BSD (PF_NETLINK and PF_ROUTE). + * - netrom: Amateur radio NetROM. * - nfc: NFC sockets. - * - vsock: vSockets. - * - kcm: Kernel Connection Multiplexor. + * - packet: Packet family. + * - phonet: Phonet sockets. + * - pppox: PPPoX sockets. * - qipcrtr: Qualcomm IPC Router. + * - rds: RDS sockets. + * - rose: Amateur Radio X.25 PLP. + * - rxrpc: RxRPC sockets. + * - security: Security callback pseudo AF. * - smc: SMC sockets. + * - sna: Linux SNA Project. + * - tipc: TIPC sockets. + * - vsock: vSockets. + * - wanpipe: Wanpipe API sockets. + * - x25: Reserved for X.25 project. * - max: The maximum value for known protocol families (this is not a protocol family). */ #ifndef _di_f_socket_address_family_e_ @@ -99,7 +99,7 @@ extern "C" { f_socket_address_family_econet_e = AF_ECONET, f_socket_address_family_ib_e = AF_IB, f_socket_address_family_ieee802154_e = AF_IEEE802154, - f_socket_address_family_inet_e = AF_INET, + f_socket_address_family_inet4_e = AF_INET, f_socket_address_family_inet6_e = AF_INET6, f_socket_address_family_ipx_e = AF_IPX, f_socket_address_family_irda_e = AF_IRDA, @@ -543,7 +543,7 @@ extern "C" { * - econet: Acorn Econet. * - ib: Native InfiniBand address. * - ieee802154: IEEE 802.15.4 sockets. - * - inet: IP protocol family. + * - inet4: IP version 4. * - inet6: IP version 6. * - ipx: Novell Internet Protocol. * - irda: IRDA sockets. @@ -591,7 +591,7 @@ extern "C" { f_socket_protocol_family_econet_e = PF_ECONET, f_socket_protocol_family_ib_e = PF_IB, f_socket_protocol_family_ieee802154_e = PF_IEEE802154, - f_socket_protocol_family_inet_e = PF_INET, + f_socket_protocol_family_inet4_e = PF_INET, f_socket_protocol_family_inet6_e = PF_INET6, f_socket_protocol_family_ipx_e = PF_IPX, f_socket_protocol_family_irda_e = PF_IRDA, @@ -735,13 +735,13 @@ extern "C" { * * id: File descriptor, with a value of -1 represents a closed file. * domain: The socket domain (protocol family, such as f_socket_protocol_family_local_e). - * protocol: The socket protocol(such as f_socket_protocol_tcp_e). + * protocol: The socket protocol (such as f_socket_protocol_tcp_e). * type: The socket type (address family, such as f_socket_address_family_local_e). * * size_read: The default number of 1-byte characters to read at a time and is often used for the read buffer size. * size_write: The default number of 1-byte characters to read at a time and is often used for the write buffer size. * - * address: Tthe socket address. + * address: The socket address. * length: The length of the socket. * * name: The name of the socket, if a name is given (for UNIX sockets this represents the path) (Must be a NULL terminated string). diff --git a/level_0/f_socket/data/build/settings-tests b/level_0/f_socket/data/build/settings-tests index 7bb2229..1795ff7 100644 --- a/level_0/f_socket/data/build/settings-tests +++ b/level_0/f_socket/data/build/settings-tests @@ -25,7 +25,7 @@ build_language c build_libraries -lc -lcmocka build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_socket -build_sources_program test-socket-accept.c test-socket-bind.c test-socket-bind_local.c test-socket-connect.c test-socket-create.c test-socket-create_pair.c test-socket-disconnect.c test-socket-listen.c test-socket-name_host.c test-socket-name_peer.c test-socket-option_get.c test-socket-option_set.c test-socket-read.c test-socket-read_message.c test-socket-read_stream.c test-socket-write.c test-socket-write_message.c test-socket-write_stream.c +build_sources_program test-socket-accept.c test-socket-bind.c test-socket-bind_inet4.c test-socket-bind_inet6.c test-socket-bind_local.c test-socket-connect.c test-socket-create.c test-socket-create_pair.c test-socket-disconnect.c test-socket-listen.c test-socket-name_host.c test-socket-name_peer.c test-socket-option_get.c test-socket-option_set.c test-socket-read.c test-socket-read_message.c test-socket-read_stream.c test-socket-write.c test-socket-write_message.c test-socket-write_stream.c build_sources_program test-socket-sockets_adjust.c test-socket-sockets_append.c test-socket-sockets_append_all.c test-socket-sockets_decimate_by.c test-socket-sockets_decrease_by.c test-socket-sockets_increase.c test-socket-sockets_increase_by.c test-socket-sockets_resize.c build_sources_program test-socket-socketss_adjust.c test-socket-socketss_append.c test-socket-socketss_append_all.c test-socket-socketss_decimate_by.c test-socket-socketss_decrease_by.c test-socket-socketss_increase.c test-socket-socketss_increase_by.c test-socket-socketss_resize.c diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.c b/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.c new file mode 100644 index 0000000..9df5460 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.c @@ -0,0 +1,102 @@ +#include "test-socket.h" +#include "test-socket-bind_inet4.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_bind_inet4__fails(void **state) { + + int errnos[] = { + EACCES, + EADDRINUSE, + EADDRNOTAVAIL, + EFAULT, + EINVAL, + ELOOP, + ENAMETOOLONG, + ENOENT, + ENOMEM, + ENOTDIR, + ENOTSOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_busy_address, + F_available_not_address, + F_buffer, + F_parameter, + F_loop, + F_string_too_large, + F_file_found_not, + F_memory_not, + F_directory_found_not, + F_socket_not, + F_failure, + }; + + { + f_socket_t socket = f_socket_t_initialize; + socket.domain = f_socket_protocol_family_inet4_e; + socket.protocol = f_socket_protocol_tcp_e; + socket.type = f_socket_address_family_inet4_e; + + for (uint8_t i = 0; i < 12; ++i) { + + will_return(__wrap_bind, true); + will_return(__wrap_bind, errnos[i]); + + const f_status_t status = f_socket_bind_inet4(&socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } + + { + f_socket_t socket = f_socket_t_initialize; + socket.domain = f_socket_protocol_family_inet4_e; + socket.protocol = f_socket_protocol_tcp_e; + socket.type = f_socket_address_family_inet4_e; + + for (uint8_t i = 0; i < 12; ++i) { + + will_return(__wrap_bind, true); + will_return(__wrap_bind, errnos[i]); + + const f_status_t status = f_socket_bind_inet4(&socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_socket_bind_inet4__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_bind_inet4(0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_bind_inet4__works(void **state) { + + { + f_socket_t socket = f_socket_t_initialize; + socket.domain = f_socket_protocol_family_inet4_e; + socket.protocol = f_socket_protocol_tcp_e; + socket.type = f_socket_address_family_inet4_e; + + will_return(__wrap_bind, false); + + const f_status_t status = f_socket_bind_inet4(&socket); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.h b/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.h new file mode 100644 index 0000000..9c556f1 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind_inet4.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_bind_inet4_h +#define _TEST__F_socket_bind_inet4_h + +/** + * Test that function fails. + * + * @see f_socket_bind_inet4() + */ +extern void test__f_socket_bind_inet4__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_bind_inet4() + */ +extern void test__f_socket_bind_inet4__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_bind_inet4() + */ +extern void test__f_socket_bind_inet4__works(void **state); + +#endif // _TEST__F_socket_bind_inet4_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.c b/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.c new file mode 100644 index 0000000..17bf2d5 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.c @@ -0,0 +1,102 @@ +#include "test-socket.h" +#include "test-socket-bind_inet6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_bind_inet6__fails(void **state) { + + int errnos[] = { + EACCES, + EADDRINUSE, + EADDRNOTAVAIL, + EFAULT, + EINVAL, + ELOOP, + ENAMETOOLONG, + ENOENT, + ENOMEM, + ENOTDIR, + ENOTSOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_busy_address, + F_available_not_address, + F_buffer, + F_parameter, + F_loop, + F_string_too_large, + F_file_found_not, + F_memory_not, + F_directory_found_not, + F_socket_not, + F_failure, + }; + + { + f_socket_t socket = f_socket_t_initialize; + socket.domain = f_socket_protocol_family_inet6_e; + socket.protocol = f_socket_protocol_tcp_e; + socket.type = f_socket_address_family_inet6_e; + + for (uint8_t i = 0; i < 12; ++i) { + + will_return(__wrap_bind, true); + will_return(__wrap_bind, errnos[i]); + + const f_status_t status = f_socket_bind_inet6(&socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } + + { + f_socket_t socket = f_socket_t_initialize; + socket.domain = f_socket_protocol_family_inet6_e; + socket.protocol = f_socket_protocol_tcp_e; + socket.type = f_socket_address_family_inet6_e; + + for (uint8_t i = 0; i < 12; ++i) { + + will_return(__wrap_bind, true); + will_return(__wrap_bind, errnos[i]); + + const f_status_t status = f_socket_bind_inet6(&socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_socket_bind_inet6__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_bind_inet6(0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_bind_inet6__works(void **state) { + + { + f_socket_t socket = f_socket_t_initialize; + socket.domain = f_socket_protocol_family_inet6_e; + socket.protocol = f_socket_protocol_tcp_e; + socket.type = f_socket_address_family_inet6_e; + + will_return(__wrap_bind, false); + + const f_status_t status = f_socket_bind_inet6(&socket); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.h b/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.h new file mode 100644 index 0000000..95d7af3 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind_inet6.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_bind_inet6_h +#define _TEST__F_socket_bind_inet6_h + +/** + * Test that function fails. + * + * @see f_socket_bind_inet6() + */ +extern void test__f_socket_bind_inet6__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_bind_inet6() + */ +extern void test__f_socket_bind_inet6__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_bind_inet6() + */ +extern void test__f_socket_bind_inet6__works(void **state); + +#endif // _TEST__F_socket_bind_inet6_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_local.c b/level_0/f_socket/tests/unit/c/test-socket-bind_local.c index 05c0193..4fa04a8 100644 --- a/level_0/f_socket/tests/unit/c/test-socket-bind_local.c +++ b/level_0/f_socket/tests/unit/c/test-socket-bind_local.c @@ -42,7 +42,6 @@ void test__f_socket_bind_local__fails(void **state) { socket.domain = f_socket_protocol_family_local_e; socket.protocol = f_socket_protocol_tcp_e; socket.type = f_socket_address_family_local_e; - socket.address.local.sun_family = f_socket_address_family_local_e; for (uint8_t i = 0; i < 12; ++i) { @@ -60,7 +59,6 @@ void test__f_socket_bind_local__fails(void **state) { socket.domain = f_socket_protocol_family_local_e; socket.protocol = f_socket_protocol_tcp_e; socket.type = f_socket_address_family_local_e; - socket.address.local.sun_family = f_socket_address_family_local_e; for (uint8_t i = 0; i < 12; ++i) { @@ -90,7 +88,6 @@ void test__f_socket_bind_local__works(void **state) { socket.domain = f_socket_protocol_family_local_e; socket.protocol = f_socket_protocol_tcp_e; socket.type = f_socket_address_family_local_e; - socket.address.local.sun_family = f_socket_address_family_local_e; will_return(__wrap_bind, false); diff --git a/level_0/f_socket/tests/unit/c/test-socket.c b/level_0/f_socket/tests/unit/c/test-socket.c index 9f8dcf1..3c0a00a 100644 --- a/level_0/f_socket/tests/unit/c/test-socket.c +++ b/level_0/f_socket/tests/unit/c/test-socket.c @@ -25,6 +25,12 @@ int main(void) { cmocka_unit_test(test__f_socket_bind__fails), cmocka_unit_test(test__f_socket_bind__works), + cmocka_unit_test(test__f_socket_bind_inet4__fails), + cmocka_unit_test(test__f_socket_bind_inet4__works), + + cmocka_unit_test(test__f_socket_bind_inet6__fails), + cmocka_unit_test(test__f_socket_bind_inet6__works), + cmocka_unit_test(test__f_socket_bind_local__fails), cmocka_unit_test(test__f_socket_bind_local__works), @@ -113,6 +119,8 @@ int main(void) { #ifndef _di_level_0_parameter_checking_ cmocka_unit_test(test__f_socket_accept__parameter_checking), cmocka_unit_test(test__f_socket_bind__parameter_checking), + cmocka_unit_test(test__f_socket_bind_inet4__parameter_checking), + cmocka_unit_test(test__f_socket_bind_inet6__parameter_checking), cmocka_unit_test(test__f_socket_bind_local__parameter_checking), cmocka_unit_test(test__f_socket_create__parameter_checking), cmocka_unit_test(test__f_socket_create_pair__parameter_checking), diff --git a/level_0/f_socket/tests/unit/c/test-socket.h b/level_0/f_socket/tests/unit/c/test-socket.h index 9205b8f..681ad71 100644 --- a/level_0/f_socket/tests/unit/c/test-socket.h +++ b/level_0/f_socket/tests/unit/c/test-socket.h @@ -28,6 +28,8 @@ // Test includes. #include "test-socket-accept.h" #include "test-socket-bind.h" +#include "test-socket-bind_inet4.h" +#include "test-socket-bind_inet6.h" #include "test-socket-bind_local.h" #include "test-socket-connect.h" #include "test-socket-create.h" -- 1.8.3.1