Page MenuHomeFreeBSD

D40064.diff
No OneTemporary

D40064.diff

diff --git a/sys/gdb/netgdb.c b/sys/gdb/netgdb.c
--- a/sys/gdb/netgdb.c
+++ b/sys/gdb/netgdb.c
@@ -57,6 +57,7 @@
#error "NetGDB cannot be used without DDB at this time"
#endif
+#include <sys/errno.h>
#include <sys/param.h>
#include <sys/kdb.h>
#include <sys/sbuf.h>
@@ -110,64 +111,27 @@
/* TODO(CEM) disable ack mode */
/*
- * Receive non-TX ACK packets on the client port.
+ * Attempt to accept the incoming packet. If we run into ENOBUFS or another
+ * error, return it.
*
- * The mbuf chain will have all non-debugnet framing headers removed
- * (ethernet, inet, udp). It will start with a debugnet_msg_hdr, of
- * which the header is guaranteed to be contiguous. If m_pullup is
- * used, the supplied in-out mbuf pointer should be updated
- * appropriately.
- *
- * If the handler frees the mbuf chain, it should set the mbuf pointer
- * to NULL. Otherwise, the debugnet input framework will free the
- * chain.
+ * The mbuf chain will have all framing headers removed (ethernet, inet, udp,
+ * debugnet).
*/
-static void
-netgdb_rx(struct debugnet_pcb *pcb, struct mbuf **mb)
+static int
+netgdb_rx(struct mbuf *m)
{
- const struct debugnet_msg_hdr *dnh;
- struct mbuf *m;
uint32_t rlen, count;
- int error;
-
- m = *mb;
- dnh = mtod(m, const void *);
-
- if (ntohl(dnh->mh_type) == DEBUGNET_FINISHED) {
- sbuf_putc(&netgdb_rxsb, CTRL('C'));
- return;
- }
-
- if (ntohl(dnh->mh_type) != DEBUGNET_DATA) {
- printf("%s: Got unexpected debugnet message %u\n",
- __func__, ntohl(dnh->mh_type));
- return;
- }
- rlen = ntohl(dnh->mh_len);
+ rlen = m->m_pkthdr.len;
#define _SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1))
if (_SBUF_FREESPACE(&netgdb_rxsb) < rlen) {
NETGDB_DEBUG("Backpressure: Not ACKing RX of packet that "
"would overflow our buffer (%zd/%zd used).\n",
netgdb_rxsb.s_len, netgdb_rxsb.s_size);
- return;
+ return (ENOBUFS);
}
#undef _SBUF_FREESPACE
- error = debugnet_ack_output(pcb, dnh->mh_seqno);
- if (error != 0) {
- printf("%s: Couldn't ACK rx packet %u; %d\n", __func__,
- ntohl(dnh->mh_seqno), error);
- /*
- * Sender will re-xmit, and assuming the condition is
- * transient, we'll process the packet's contentss later.
- */
- return;
- }
-
- m_adj(m, sizeof(*dnh));
- dnh = NULL;
-
/*
* Inlined m_apply -- why isn't there a macro or inline function
* version?
@@ -181,6 +145,13 @@
rlen -= count;
m = m->m_next;
}
+ return (0);
+}
+
+static void
+netgdb_finish(void)
+{
+ sbuf_putc(&netgdb_rxsb, CTRL('C'));
}
/*
@@ -338,6 +309,7 @@
struct debugnet_ddb_config params;
struct debugnet_conn_params dcp;
struct debugnet_pcb *pcb;
+ char proxy_buf[INET_ADDRSTRLEN];
int error;
if (!KERNEL_PANICKED()) {
@@ -374,6 +346,7 @@
.dc_client_port = NETGDB_CLIENTPORT,
.dc_herald_aux2 = NETGDB_PROTO_V1,
.dc_rx_handler = netgdb_rx,
+ .dc_finish_handler = netgdb_finish,
};
error = debugnet_connect(&dcp, &pcb);
@@ -398,6 +371,19 @@
db_cmd_loop_done = 1;
gdb_return_to_ddb = true;
db_printf("(detaching GDB will return control to DDB)\n");
+
+ const in_addr_t *proxy_addr = debugnet_get_server_addr(netgdb_conn);
+ const uint16_t proxy_port = debugnet_get_server_port(netgdb_conn) + 1;
+ inet_ntop(AF_INET, proxy_addr, proxy_buf, sizeof(proxy_buf));
+ if (inet_ntop(AF_INET, proxy_addr, proxy_buf, sizeof(proxy_buf)) == NULL) {
+ db_printf("Connected to proxy. "
+ "Use target remote <proxy address>:%hu to begin debugging.\n",
+ proxy_port);
+ } else {
+ db_printf("Connected to proxy. "
+ "Use target remote %s:%hu to begin debugging.\n",
+ proxy_buf, proxy_port);
+ }
#if 0
/* Aspirational, but does not work reliably. */
db_printf("(ctrl-c will return control to ddb)\n");
diff --git a/sys/net/debugnet.h b/sys/net/debugnet.h
--- a/sys/net/debugnet.h
+++ b/sys/net/debugnet.h
@@ -134,7 +134,10 @@
*
* The handler should ACK receieved packets with debugnet_ack_output.
*/
- void (*dc_rx_handler)(struct debugnet_pcb *, struct mbuf **);
+ int (*dc_rx_handler)(struct mbuf *);
+
+ /* Cleanup signal for bidirectional protocols. */
+ void (*dc_finish_handler)(void);
};
/*
@@ -207,6 +210,16 @@
*/
const unsigned char *debugnet_get_gw_mac(const struct debugnet_pcb *);
+/*
+ * Get the connected server address.
+ */
+const in_addr_t *debugnet_get_server_addr(const struct debugnet_pcb *);
+
+/*
+ * Get the connected server port.
+ */
+const uint16_t debugnet_get_server_port(const struct debugnet_pcb *);
+
/*
* Callbacks from core mbuf code.
*/
diff --git a/sys/net/debugnet.c b/sys/net/debugnet.c
--- a/sys/net/debugnet.c
+++ b/sys/net/debugnet.c
@@ -115,6 +115,22 @@
return (pcb->dp_gw_mac.octet);
}
+const in_addr_t *
+debugnet_get_server_addr(const struct debugnet_pcb *pcb)
+{
+ MPASS(g_debugnet_pcb_inuse && pcb == &g_dnet_pcb &&
+ pcb->dp_state >= DN_STATE_GOT_HERALD_PORT);
+ return (&pcb->dp_server);
+}
+
+const uint16_t
+debugnet_get_server_port(const struct debugnet_pcb *pcb)
+{
+ MPASS(g_debugnet_pcb_inuse && pcb == &g_dnet_pcb &&
+ pcb->dp_state >= DN_STATE_GOT_HERALD_PORT);
+ return (pcb->dp_server_port);
+}
+
/*
* Start of network primitives, beginning with output primitives.
*/
@@ -365,6 +381,8 @@
{
const struct debugnet_msg_hdr *dnh;
struct mbuf *m;
+ uint32_t hdr_type;
+ uint32_t seqno;
int error;
m = *mb;
@@ -383,33 +401,46 @@
return;
}
}
- dnh = mtod(m, const void *);
+ dnh = mtod(m, const void *);
if (ntohl(dnh->mh_len) + sizeof(*dnh) > m->m_pkthdr.len) {
DNETDEBUG("Dropping short packet.\n");
return;
}
+ hdr_type = ntohl(dnh->mh_type);
+ if (hdr_type != DEBUGNET_DATA) {
+ if (hdr_type == DEBUGNET_FINISHED) {
+ printf("Remote shut down the connection on us!\n");
+ pcb->dp_state = DN_STATE_REMOTE_CLOSED;
+ if (pcb->dp_finish_handler != NULL) {
+ pcb->dp_finish_handler();
+ }
+ } else {
+ DNETDEBUG("Got unexpected debugnet message %u\n", hdr_type);
+ }
+ return;
+ }
+
/*
* If the issue is transient (ENOBUFS), sender should resend. If
* non-transient (like driver objecting to rx -> tx from the same
* thread), not much else we can do.
*/
- error = debugnet_ack_output(pcb, dnh->mh_seqno);
- if (error != 0)
+ seqno = dnh->mh_seqno; /* net endian */
+ m_adj(m, sizeof(*dnh));
+ dnh = NULL;
+ error = pcb->dp_rx_handler(m);
+ if (error != 0) {
+ DNETDEBUG("RX handler was not able to accept message, error %d. "
+ "Skipping ack.\n", error);
return;
-
- if (ntohl(dnh->mh_type) == DEBUGNET_FINISHED) {
- printf("Remote shut down the connection on us!\n");
- pcb->dp_state = DN_STATE_REMOTE_CLOSED;
-
- /*
- * Continue through to the user handler so they are signalled
- * not to wait for further rx.
- */
}
- pcb->dp_rx_handler(pcb, mb);
+ error = debugnet_ack_output(pcb, seqno);
+ if (error != 0) {
+ DNETDEBUG("Couldn't ACK rx packet %u; %d\n", ntohl(seqno), error);
+ }
}
static void
diff --git a/sys/net/debugnet_int.h b/sys/net/debugnet_int.h
--- a/sys/net/debugnet_int.h
+++ b/sys/net/debugnet_int.h
@@ -69,8 +69,10 @@
void (*dp_drv_input)(struct ifnet *, struct mbuf *);
/* RX handler for bidirectional protocols. */
- void (*dp_rx_handler)(struct debugnet_pcb *,
- struct mbuf **);
+ int (*dp_rx_handler)(struct mbuf *);
+
+ /* Cleanup signal for bidirectional protocols. */
+ void (*dp_finish_handler)(void);
enum dnet_pcb_st dp_state;
uint16_t dp_client_port;

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 6:08 PM (10 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28598956
Default Alt Text
D40064.diff (7 KB)

Event Timeline