Skip to content

Commit 033ad47

Browse files
committed
Drv: rename hostname to ipv4Address
1 parent d228151 commit 033ad47

16 files changed

Lines changed: 187 additions & 116 deletions

Drv/Ip/IpSocket.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,27 @@
4545
namespace Drv {
4646

4747
IpSocket::IpSocket() : m_timeoutSeconds(0), m_timeoutMicroseconds(0), m_port(0) {
48-
::memset(m_hostname, 0, sizeof(m_hostname));
48+
::memset(this->m_ipv4_address, 0, sizeof(this->m_ipv4_address));
4949
}
5050

51-
SocketIpStatus IpSocket::configure(const char* const hostname,
51+
SocketIpStatus IpSocket::configure(const char* const ipv4_address,
5252
const U16 port,
5353
const U32 timeout_seconds,
5454
const U32 timeout_microseconds) {
5555
FW_ASSERT(timeout_microseconds < 1000000, static_cast<FwAssertArgType>(timeout_microseconds));
5656
FW_ASSERT(this->isValidPort(port), static_cast<FwAssertArgType>(port));
57-
FW_ASSERT(hostname != nullptr);
57+
FW_ASSERT(ipv4_address != nullptr);
58+
// Defense-in-depth: reject inputs that would have been silently truncated by string_copy.
59+
FW_ASSERT(Fw::StringUtils::string_length(ipv4_address,
60+
static_cast<FwSizeType>(SOCKET_MAX_IPV4_ADDRESS_SIZE))
61+
< static_cast<FwSizeType>(SOCKET_MAX_IPV4_ADDRESS_SIZE));
5862
this->m_timeoutSeconds = timeout_seconds;
5963
this->m_timeoutMicroseconds = timeout_microseconds;
6064
this->m_port = port;
61-
(void)Fw::StringUtils::string_copy(this->m_hostname, hostname, static_cast<FwSizeType>(SOCKET_MAX_HOSTNAME_SIZE));
65+
(void)Fw::StringUtils::string_copy(this->m_ipv4_address, ipv4_address,
66+
static_cast<FwSizeType>(SOCKET_MAX_IPV4_ADDRESS_SIZE));
67+
// Post-condition: NUL termination guaranteed by Fw::StringUtils::string_copy contract.
68+
FW_ASSERT(this->m_ipv4_address[SOCKET_MAX_IPV4_ADDRESS_SIZE - 1] == '\0');
6269
return SOCK_SUCCESS;
6370
}
6471

@@ -83,23 +90,29 @@ SocketIpStatus IpSocket::setupTimeouts(int socketFd) {
8390
return SOCK_SUCCESS;
8491
}
8592

86-
SocketIpStatus IpSocket::addressToIp4(const char* address, void* ip4) {
87-
FW_ASSERT(address != nullptr);
88-
FW_ASSERT(ip4 != nullptr);
93+
SocketIpStatus IpSocket::addressToIp4(const char* const ipv4_address, void* const out) {
94+
FW_ASSERT(ipv4_address != nullptr);
95+
FW_ASSERT(out != nullptr);
96+
// Pre-zero the destination so that on failure, callers cannot accidentally consume
97+
// uninitialized memory. This is a defense-in-depth measure for safety-critical use.
98+
(void)::memset(out, 0, sizeof(struct in_addr));
8999
// Get the IP address from host
90100
#ifdef TGT_OS_TYPE_VXWORKS
91-
int ip = inet_addr(address);
101+
int ip = inet_addr(ipv4_address);
92102
if (ip == ERROR) {
93103
return SOCK_INVALID_IP_ADDRESS;
94104
}
95105
// from sin_addr, which has one struct
96106
// member s_addr, which is unsigned int
97-
*reinterpret_cast<unsigned long*>(ip4) = ip;
107+
*static_cast<unsigned long*>(out) = static_cast<unsigned long>(ip);
98108
#else
99-
// First IP address to socket sin_addr
100-
if (not ::inet_pton(AF_INET, address, ip4)) {
109+
// inet_pton(3) returns 1 on success, 0 if the input is not a valid IPv4 presentation
110+
// string, and -1 (with errno=EAFNOSUPPORT) if the family argument is bogus. Only a
111+
// strict equality check is safe — a `not` test treats -1 as success and would silently
112+
// mask an EAFNOSUPPORT failure. (Power-of-Ten Rule 7: check every return value.)
113+
if (::inet_pton(AF_INET, ipv4_address, out) != 1) {
101114
return SOCK_INVALID_IP_ADDRESS;
102-
};
115+
}
103116
#endif
104117
return SOCK_SUCCESS;
105118
}

Drv/Ip/IpSocket.hpp

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,32 @@ class IpSocket {
5959
IpSocket();
6060
virtual ~IpSocket() {};
6161
/**
62-
* \brief configure the ip socket with host and transmission timeouts
62+
* \brief configure the ip socket with an IPv4 address and transmission timeouts
6363
*
64-
* Configures the IP handler (Tcp, Tcp server, and Udp) to use the given hostname and port. When multiple ports are
65-
* used for send/receive these settings affect the send direction (as is the case for udp). Hostname DNS translation
66-
* is left up to the caller and thus hostname must be an IP address in dot-notation of the form "x.x.x.x". Port
67-
* cannot be set to 0 as dynamic port assignment is not supported.
64+
* Configures the IP handler (Tcp, Tcp server, and Udp) to use the given IPv4 address and port.
65+
* When multiple ports are used for send/receive these settings affect the send direction (as is
66+
* the case for udp).
6867
*
69-
* Note: for UDP sockets this is equivalent to `configureSend` and only sets up the transmission direction of the
70-
* socket. A separate call to `configureRecv` is required to receive on the socket and should be made before the
71-
* `open` call has been made.
68+
* \warning DNS resolution is NOT performed by this driver. The \a ipv4_address argument MUST be
69+
* a NUL-terminated IPv4 address in dotted-quad notation of the form "x.x.x.x" (for example,
70+
* "127.0.0.1"). Passing a textual hostname (e.g. "localhost") will be rejected at open() time
71+
* with SOCK_INVALID_IP_ADDRESS. Callers that need DNS lookup must perform it themselves and
72+
* pass the resolved IPv4 string to this function.
7273
*
73-
* \param hostname: socket uses for outgoing transmissions (and incoming when tcp). Must be of form x.x.x.x
74+
* Port cannot be set to 0 as dynamic port assignment is not supported.
75+
*
76+
* Note: for UDP sockets this is equivalent to `configureSend` and only sets up the
77+
* transmission direction of the socket. A separate call to `configureRecv` is required to
78+
* receive on the socket and should be made before the `open` call has been made.
79+
*
80+
* \param ipv4_address: IPv4 address (dotted-quad "x.x.x.x") used for outgoing transmissions
81+
* (and incoming when tcp).
7482
* \param port: port socket uses for outgoing transmissions (and incoming when tcp). Must NOT be 0.
7583
* \param send_timeout_seconds: send timeout seconds portion
7684
* \param send_timeout_microseconds: send timeout microseconds portion. Must be less than 1000000
7785
* \return status of configure
7886
*/
79-
virtual SocketIpStatus configure(const char* hostname,
87+
virtual SocketIpStatus configure(const char* const ipv4_address,
8088
const U16 port,
8189
const U32 send_timeout_seconds,
8290
const U32 send_timeout_microseconds);
@@ -179,12 +187,18 @@ class IpSocket {
179187
SocketIpStatus setupTimeouts(int socketFd);
180188

181189
/**
182-
* \brief converts a given address in dot form x.x.x.x to an ip address. ONLY works for IPv4.
183-
* \param address: address to convert
184-
* \param ip4: IPv4 representation structure to fill
185-
* \return: status of conversion
190+
* \brief converts a given IPv4 address in dotted-quad form "x.x.x.x" to a network-order
191+
* in_addr structure. ONLY works for IPv4; does NOT perform DNS resolution.
192+
*
193+
* On failure the destination buffer is zero-initialized so callers cannot accidentally
194+
* consume uninitialized stack memory after a failed conversion.
195+
*
196+
* \param ipv4_address: NUL-terminated dotted-quad IPv4 address to convert (must not be null)
197+
* \param out: pointer to a struct in_addr (or equivalently sized buffer) to fill
198+
* (must not be null)
199+
* \return: SOCK_SUCCESS on success, SOCK_INVALID_IP_ADDRESS on any malformed input
186200
*/
187-
static SocketIpStatus addressToIp4(const char* address, void* ip4);
201+
static SocketIpStatus addressToIp4(const char* const ipv4_address, void* const out);
188202
/**
189203
* \brief Protocol specific open implementation, called from open.
190204
* \param socketDescriptor: (output) socket descriptor opened. Only valid on SOCK_SUCCESS. Otherwise will be invalid
@@ -233,8 +247,8 @@ class IpSocket {
233247

234248
U32 m_timeoutSeconds;
235249
U32 m_timeoutMicroseconds;
236-
U16 m_port; //!< IP address port used
237-
char m_hostname[SOCKET_MAX_HOSTNAME_SIZE]; //!< Hostname to supply
250+
U16 m_port; //!< IP address port used
251+
char m_ipv4_address[SOCKET_MAX_IPV4_ADDRESS_SIZE];//!< IPv4 address (dotted-quad "x.x.x.x")
238252
};
239253
} // namespace Drv
240254

Drv/Ip/TcpClientSocket.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ SocketIpStatus TcpClientSocket::openProtocol(SocketDescriptor& socketDescriptor)
6363
address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
6464
#endif
6565

66-
// First IP address to socket sin_addr
67-
if (IpSocket::addressToIp4(m_hostname, &(address.sin_addr)) != SOCK_SUCCESS) {
66+
// Convert the configured IPv4 address (dotted-quad) to a network-order in_addr.
67+
if (IpSocket::addressToIp4(this->m_ipv4_address, &(address.sin_addr)) != SOCK_SUCCESS) {
6868
::close(socketFd);
6969
return SOCK_INVALID_IP_ADDRESS;
7070
};
@@ -86,7 +86,7 @@ SocketIpStatus TcpClientSocket::openProtocol(SocketDescriptor& socketDescriptor)
8686
return SOCK_FAILED_TO_CONNECT;
8787
}
8888
socketDescriptor.fd = socketFd;
89-
Fw::Logger::log("Connected to %s:%hu as a tcp client\n", m_hostname, m_port);
89+
Fw::Logger::log("Connected to %s:%hu as a tcp client\n", this->m_ipv4_address, this->m_port);
9090
return SOCK_SUCCESS;
9191
}
9292

Drv/Ip/TcpServerSocket.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ SocketIpStatus TcpServerSocket::startup(SocketDescriptor& socketDescriptor) {
6060
#if defined TGT_OS_TYPE_VXWORKS || TGT_OS_TYPE_DARWIN
6161
address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
6262
#endif
63-
// First IP address to socket sin_addr
64-
if (IpSocket::addressToIp4(m_hostname, &(address.sin_addr)) != SOCK_SUCCESS) {
63+
// Convert the configured IPv4 address (dotted-quad) to a network-order in_addr.
64+
if (IpSocket::addressToIp4(this->m_ipv4_address, &(address.sin_addr)) != SOCK_SUCCESS) {
6565
::close(serverFd);
6666
return SOCK_INVALID_IP_ADDRESS;
6767
};
@@ -88,7 +88,7 @@ SocketIpStatus TcpServerSocket::startup(SocketDescriptor& socketDescriptor) {
8888
::close(serverFd);
8989
return SOCK_FAILED_TO_LISTEN; // What we have here is a failure to communicate
9090
}
91-
Fw::Logger::log("Listening for single client at %s:%hu\n", m_hostname, m_port);
91+
Fw::Logger::log("Listening for single client at %s:%hu\n", this->m_ipv4_address, this->m_port);
9292
FW_ASSERT(serverFd != -1);
9393
socketDescriptor.serverFd = serverFd;
9494
this->m_port = ntohs(address.sin_port);
@@ -119,7 +119,7 @@ SocketIpStatus TcpServerSocket::openProtocol(SocketDescriptor& socketDescriptor)
119119
return SOCK_FAILED_TO_SET_SOCKET_OPTIONS;
120120
}
121121

122-
Fw::Logger::log("Accepted client at %s:%hu\n", m_hostname, m_port);
122+
Fw::Logger::log("Accepted client at %s:%hu\n", this->m_ipv4_address, this->m_port);
123123
socketDescriptor.fd = clientFd;
124124
return SOCK_SUCCESS;
125125
}

Drv/Ip/UdpSocket.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,42 @@ UdpSocket::UdpSocket() : IpSocket(), m_recv_configured(false) {
4646

4747
UdpSocket::~UdpSocket() = default;
4848

49-
SocketIpStatus UdpSocket::configure(const char* const hostname,
49+
SocketIpStatus UdpSocket::configure(const char* const ipv4_address,
5050
const U16 port,
5151
const U32 timeout_seconds,
5252
const U32 timeout_microseconds) {
53+
(void)ipv4_address;
54+
(void)port;
55+
(void)timeout_seconds;
56+
(void)timeout_microseconds;
5357
FW_ASSERT(0); // Must use configureSend and/or configureRecv
5458
return SocketIpStatus::SOCK_INVALID_CALL;
5559
}
5660

57-
SocketIpStatus UdpSocket::configureSend(const char* const hostname,
61+
SocketIpStatus UdpSocket::configureSend(const char* const ipv4_address,
5862
const U16 port,
5963
const U32 timeout_seconds,
6064
const U32 timeout_microseconds) {
61-
FW_ASSERT(hostname != nullptr);
65+
FW_ASSERT(ipv4_address != nullptr);
6266
FW_ASSERT(this->isValidPort(port));
6367
FW_ASSERT(timeout_microseconds < 1000000);
64-
return IpSocket::configure(hostname, port, timeout_seconds, timeout_microseconds);
68+
return IpSocket::configure(ipv4_address, port, timeout_seconds, timeout_microseconds);
6569
}
6670

67-
SocketIpStatus UdpSocket::configureRecv(const char* hostname, const U16 port) {
68-
FW_ASSERT(hostname != nullptr);
71+
SocketIpStatus UdpSocket::configureRecv(const char* const ipv4_address, const U16 port) {
72+
FW_ASSERT(ipv4_address != nullptr);
6973
FW_ASSERT(this->isValidPort(port));
70-
FW_ASSERT(Fw::StringUtils::string_length(hostname, SOCKET_MAX_HOSTNAME_SIZE) < SOCKET_MAX_HOSTNAME_SIZE);
74+
FW_ASSERT(Fw::StringUtils::string_length(ipv4_address,
75+
static_cast<FwSizeType>(SOCKET_MAX_IPV4_ADDRESS_SIZE))
76+
< static_cast<FwSizeType>(SOCKET_MAX_IPV4_ADDRESS_SIZE));
7177

7278
// Initialize the receive address structure
7379
(void)::memset(&m_addr_recv, 0, sizeof(m_addr_recv));
7480
m_addr_recv.sin_family = AF_INET;
7581
m_addr_recv.sin_port = htons(port);
7682

77-
// Convert hostname to IP address
78-
SocketIpStatus status = IpSocket::addressToIp4(hostname, &m_addr_recv.sin_addr);
83+
// Convert IPv4 address (dotted-quad) to network-order in_addr
84+
SocketIpStatus status = IpSocket::addressToIp4(ipv4_address, &m_addr_recv.sin_addr);
7985
if (status != SOCK_SUCCESS) {
8086
return status;
8187
}
@@ -143,10 +149,11 @@ SocketIpStatus UdpSocket::openProtocol(SocketDescriptor& socketDescriptor) {
143149
address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
144150
#endif
145151

146-
// First IP address to socket sin_addr
147-
status = IpSocket::addressToIp4(m_hostname, &(address.sin_addr));
152+
// Convert the configured IPv4 address (dotted-quad) to a network-order in_addr.
153+
status = IpSocket::addressToIp4(this->m_ipv4_address, &(address.sin_addr));
148154
if (status != SOCK_SUCCESS) {
149-
Fw::Logger::log("Failed to resolve hostname %s: %d\n", m_hostname, static_cast<I32>(status));
155+
Fw::Logger::log("Failed to parse IPv4 address %s: %d\n",
156+
this->m_ipv4_address, static_cast<I32>(status));
150157
::close(socketFd);
151158
return status;
152159
};
@@ -187,9 +194,10 @@ SocketIpStatus UdpSocket::openProtocol(SocketDescriptor& socketDescriptor) {
187194
if ((port == 0) && (recv_port > 0)) {
188195
Fw::Logger::log("Setup to only receive udp at %s:%hu\n", recv_addr, recv_port);
189196
} else if ((port > 0) && (recv_port == 0)) {
190-
Fw::Logger::log("Setup to only send udp at %s:%hu\n", m_hostname, port);
197+
Fw::Logger::log("Setup to only send udp at %s:%hu\n", this->m_ipv4_address, port);
191198
} else if ((port > 0) && (recv_port > 0)) {
192-
Fw::Logger::log("Setup to receive udp at %s:%hu and send to %s:%hu\n", recv_addr, recv_port, m_hostname, port);
199+
Fw::Logger::log("Setup to receive udp at %s:%hu and send to %s:%hu\n",
200+
recv_addr, recv_port, this->m_ipv4_address, port);
193201
}
194202

195203
FW_ASSERT(status == SOCK_SUCCESS, static_cast<FwAssertArgType>(status));

Drv/Ip/UdpSocket.hpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,48 +57,58 @@ class UdpSocket : public IpSocket {
5757
*
5858
* \warning configure is disabled for UdpSocket. Use configureSend and configureRecv instead.
5959
*/
60-
SocketIpStatus configure(const char* hostname,
60+
SocketIpStatus configure(const char* const ipv4_address,
6161
const U16 port,
6262
const U32 send_timeout_seconds,
6363
const U32 send_timeout_microseconds) override;
6464

6565
/**
6666
* \brief configure the udp socket for outgoing transmissions
6767
*
68-
* Configures the UDP handler to use the given hostname and port for outgoing transmissions. Incoming hostname
69-
* and port are configured using the `configureRecv` function call for UDP as it requires separate host/port pairs
70-
* for outgoing and incoming transmissions. Hostname DNS translation is left up to the caller and thus hostname must
71-
* be an IP address in dot-notation of the form "x.x.x.x". If port is set to 0, the socket will be configured for
72-
* ephemeral send (dynamic reply-to) and will use the sender's address from the first received datagram for replies.
73-
* It is possible to configure the UDP port as a single-direction send port only.
68+
* Configures the UDP handler to use the given IPv4 address and port for outgoing
69+
* transmissions. Incoming address and port are configured using the `configureRecv`
70+
* function call for UDP as it requires separate address/port pairs for outgoing and
71+
* incoming transmissions.
72+
*
73+
* \warning DNS resolution is NOT performed by this driver. The \a ipv4_address argument
74+
* MUST be a NUL-terminated IPv4 address in dotted-quad notation of the form "x.x.x.x".
75+
* Callers that need DNS lookup must perform it themselves.
76+
*
77+
* If port is set to 0, the socket will be configured for ephemeral send (dynamic
78+
* reply-to) and will use the sender's address from the first received datagram for
79+
* replies. It is possible to configure the UDP port as a single-direction send port only.
7480
*
7581
* Note: delegates to `IpSocket::configure`
7682
*
77-
* \param hostname: socket uses for outgoing transmissions. Must be of form x.x.x.x
83+
* \param ipv4_address: IPv4 address (dotted-quad "x.x.x.x") for outgoing transmissions.
7884
* \param port: port socket uses for outgoing transmissions. Can be 0 for ephemeral reply-to mode.
7985
* \param send_timeout_seconds: send timeout seconds portion
8086
* \param send_timeout_microseconds: send timeout microseconds portion. Must be less than 1000000
8187
* \return status of configure
8288
*/
83-
SocketIpStatus configureSend(const char* hostname,
89+
SocketIpStatus configureSend(const char* const ipv4_address,
8490
const U16 port,
8591
const U32 send_timeout_seconds,
8692
const U32 send_timeout_microseconds);
8793

8894
/**
8995
* \brief configure the udp socket for incoming transmissions
9096
*
91-
* Configures the UDP handler to use the given hostname and port for incoming transmissions. Outgoing hostname
92-
* and port are configured using the `configureSend` function call for UDP as it requires separate host/port pairs
93-
* for outgoing and incoming transmissions. Hostname DNS translation is left up to the caller and thus hostname must
94-
* be an IP address in dot-notation of the form "x.x.x.x". It is possible to configure the UDP port as a
95-
* single-direction receive port only.
97+
* Configures the UDP handler to use the given IPv4 address and port for incoming
98+
* transmissions. Outgoing address and port are configured using the `configureSend`
99+
* function call for UDP as it requires separate address/port pairs for outgoing and
100+
* incoming transmissions.
101+
*
102+
* \warning DNS resolution is NOT performed by this driver. The \a ipv4_address argument
103+
* MUST be a NUL-terminated IPv4 address in dotted-quad notation of the form "x.x.x.x".
104+
*
105+
* It is possible to configure the UDP port as a single-direction receive port only.
96106
*
97-
* \param hostname: socket uses for incoming transmissions. Must be of form x.x.x.x
107+
* \param ipv4_address: IPv4 address (dotted-quad "x.x.x.x") to bind for receiving.
98108
* \param port: port socket uses for incoming transmissions. Can be 0 for ephemeral port assignment.
99109
* \return status of configure
100110
*/
101-
SocketIpStatus configureRecv(const char* hostname, const U16 port);
111+
SocketIpStatus configureRecv(const char* const ipv4_address, const U16 port);
102112

103113
/**
104114
* \brief get the port being received on

0 commit comments

Comments
 (0)