zhhyu7 commented on code in PR #20627:
URL: https://github.com/apache/nuttx/pull/20627#discussion_r4281369977
##########
net/tcp/tcp_input.c:
##########
@@ -1570,38 +1573,57 @@ static void tcp_input(FAR struct net_driver_s *dev,
uint8_t domain,
if ((tcp->flags & TCP_URG) != 0)
{
- dev->d_urglen = (tcp->urgp[0] << 8) | tcp->urgp[1];
- if (dev->d_urglen > dev->d_len)
+ uint16_t urgp = (tcp->urgp[0] << 8) | tcp->urgp[1];
+
+ /* BSD/Linux default semantics (tcp_stdurg=0):
+ * The urgent pointer points ONE BYTE PAST the urgent byte.
+ * The single urgent byte is at payload[urgp - 1].
+ *
+ * If urgp is within the current segment (1 <= urgp <= d_len):
+ * - Extract the single urgent byte into conn->urg_data from
+ * the IOB chain.
+ * - Record state as TCP_URG_VALID.
+ * - Signal urgent data availability (flags |= TCP_URGDATA).
+ *
+ * If urgp > d_len:
+ * - The urgent byte is located in a future segment not yet
+ * received; mark state as TCP_URG_AWAITING.
+ * - Signal urgent data (flags |= TCP_URGDATA).
+ */
+
+ if (urgp >= 1 && urgp <= dev->d_len)
{
- /* There is more urgent data in the next segment to come. */
+ int app_offset;
+
+ /* Payload is stored in an IOB chain starting at dev->d_iob.
+ * Calculate the offset of d_appdata within dev->d_iob.
+ */
- dev->d_urglen = dev->d_len;
+ app_offset = (dev->d_appdata - dev->d_iob->io_data) -
+ dev->d_iob->io_offset;
+
+ /* Copy the urgent byte safely from the IOB chain */
+
+ iob_copyout(&conn->urg_data, dev->d_iob, 1,
+ app_offset + urgp - 1);
Review Comment:
The urgent byte is now copied into ```conn->urg_data```, but the
```payload``` is not modified, and the position of the urgent byte in the
stream is not recorded. Without ```SO_OOBINLINE```, the application therefore
receives the urgent byte twice: once from ```recv(MSG_OOB)``` and once in the
normal stream?
##########
net/tcp/tcp_send_buffered.c:
##########
@@ -1656,7 +1718,16 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR
const void *buf,
* conn->write_q
*/
+#ifdef CONFIG_NET_TCPURGDATA
+ if ((flags & MSG_OOB) != 0)
+ {
+ wrb->wb_urg = TCP_WBPKTLEN(wrb);
Review Comment:
```psock_tcp_send()``` splits the user buffer into wrbs of at most
```tcp_max_wrb_size()``` bytes (the loop that starts at line 1463 and advances
at line 1764). ```wb_urg = TCP_WBPKTLEN(wrb)``` runs for every chunk, so each
wrb gets its own urgent mark.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]