Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Feb 2018 19:49:15 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r329339 - head/stand/libsa
Message-ID:  <201802151949.w1FJnFS4044411@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Thu Feb 15 19:49:15 2018
New Revision: 329339
URL: https://svnweb.freebsd.org/changeset/base/329339

Log:
  libsa: Consolidate tftp sendrecv into net.c sendrecv
  
  bootp/arp/rarp/rpc all use the sendrecv implementation in net.c. tftp has
  its own implementation because it passes an extra parameter into the recv
  callback for the received payload type to be held.
  
  These sendrecv implementations are otherwise equivalent, so consolidate
  them. The other users of sendrecv won't be using the extra argument to recv,
  but this gives us only one place to worry about respecting timeouts and one
  consistent timeout behavior.
  
  Tested by:	sbruno
  Reviewed by:	sbruno, tsoome
  MFC after:	1 week
  Differential Revision:	https://reviews.freebsd.org/D14373

Modified:
  head/stand/libsa/arp.c
  head/stand/libsa/bootp.c
  head/stand/libsa/net.c
  head/stand/libsa/net.h
  head/stand/libsa/rarp.c
  head/stand/libsa/rpc.c
  head/stand/libsa/tftp.c

Modified: head/stand/libsa/arp.c
==============================================================================
--- head/stand/libsa/arp.c	Thu Feb 15 18:58:03 2018	(r329338)
+++ head/stand/libsa/arp.c	Thu Feb 15 19:49:15 2018	(r329339)
@@ -65,7 +65,7 @@ int arp_num = 1;
 
 /* Local forwards */
 static	ssize_t arpsend(struct iodesc *, void *, size_t);
-static	ssize_t arprecv(struct iodesc *, void **, void **, time_t);
+static	ssize_t arprecv(struct iodesc *, void **, void **, time_t, void *);
 
 /* Broadcast an ARP packet, asking who has addr on interface d */
 u_char *
@@ -118,7 +118,7 @@ arpwhohas(struct iodesc *d, struct in_addr addr)
 	ah = NULL;
 	i = sendrecv(d,
 	    arpsend, &wbuf.data, sizeof(wbuf.data),
-	    arprecv, &pkt, (void **)&ah);
+	    arprecv, &pkt, (void **)&ah, NULL);
 	if (i == -1) {
 		panic("arp: no response for %s\n",
 			  inet_ntoa(addr));
@@ -160,7 +160,7 @@ arpsend(struct iodesc *d, void *pkt, size_t len)
  * else -1 (and errno == 0)
  */
 static ssize_t
-arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft)
+arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra)
 {
 	ssize_t n;
 	struct ether_arp *ah;

Modified: head/stand/libsa/bootp.c
==============================================================================
--- head/stand/libsa/bootp.c	Thu Feb 15 18:58:03 2018	(r329338)
+++ head/stand/libsa/bootp.c	Thu Feb 15 19:49:15 2018	(r329339)
@@ -73,7 +73,7 @@ static	char vm_cmu[4] = VM_CMU;
 
 /* Local forwards */
 static	ssize_t bootpsend(struct iodesc *, void *, size_t);
-static	ssize_t bootprecv(struct iodesc *, void **, void **, time_t);
+static	ssize_t bootprecv(struct iodesc *, void **, void **, time_t, void *);
 static	int vend_rfc1048(u_char *, u_int);
 #ifdef BOOTP_VEND_CMU
 static	void vend_cmu(u_char *);
@@ -183,7 +183,7 @@ bootp(int sock)
 
 	if(sendrecv(d,
 		    bootpsend, bp, sizeof(*bp),
-		    bootprecv, &pkt, (void **)&rbootp) == -1) {
+		    bootprecv, &pkt, (void **)&rbootp, NULL) == -1) {
 	    printf("bootp: no reply\n");
 	    return;
 	}
@@ -209,7 +209,7 @@ bootp(int sock)
 		free(pkt);
 		if(sendrecv(d,
 			    bootpsend, bp, sizeof(*bp),
-			    bootprecv, &pkt, (void **)&rbootp) == -1) {
+			    bootprecv, &pkt, (void **)&rbootp, NULL) == -1) {
 			printf("DHCPREQUEST failed\n");
 			return;
 		}
@@ -286,7 +286,8 @@ bootpsend(struct iodesc *d, void *pkt, size_t len)
 }
 
 static ssize_t
-bootprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft)
+bootprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft,
+    void *extra)
 {
 	ssize_t n;
 	struct bootp *bp;

Modified: head/stand/libsa/net.c
==============================================================================
--- head/stand/libsa/net.c	Thu Feb 15 18:58:03 2018	(r329338)
+++ head/stand/libsa/net.c	Thu Feb 15 19:49:15 2018	(r329339)
@@ -72,8 +72,8 @@ ssize_t
 sendrecv(struct iodesc *d,
     ssize_t (*sproc)(struct iodesc *, void *, size_t),
     void *sbuf, size_t ssize,
-    ssize_t (*rproc)(struct iodesc *, void **, void **, time_t),
-    void **pkt, void **payload)
+    ssize_t (*rproc)(struct iodesc *, void **, void **, time_t, void *),
+    void **pkt, void **payload, void *recv_extra)
 {
 	ssize_t cc;
 	time_t t, tmo, tlast;
@@ -116,7 +116,7 @@ sendrecv(struct iodesc *d,
 		}
 
 		/* Try to get a packet and process it. */
-		cc = (*rproc)(d, pkt, payload, tleft);
+		cc = (*rproc)(d, pkt, payload, tleft, recv_extra);
 		/* Return on data, EOF or real error. */
 		if (cc != -1 || (errno != 0 && errno != ETIMEDOUT))
 			return (cc);

Modified: head/stand/libsa/net.h
==============================================================================
--- head/stand/libsa/net.h	Thu Feb 15 18:58:03 2018	(r329338)
+++ head/stand/libsa/net.h	Thu Feb 15 19:49:15 2018	(r329339)
@@ -115,8 +115,9 @@ ssize_t	readudp(struct iodesc *, void **, void **, tim
 ssize_t	sendrecv(struct iodesc *,
 			ssize_t (*)(struct iodesc *, void *, size_t),
 			void *, size_t,
-			ssize_t (*)(struct iodesc *, void **, void **, time_t),
-			void **, void **);
+			ssize_t (*)(struct iodesc *, void **, void **, time_t,
+			    void *),
+			void **, void **, void *);
 
 /* bootp/DHCP */
 void	bootp(int);

Modified: head/stand/libsa/rarp.c
==============================================================================
--- head/stand/libsa/rarp.c	Thu Feb 15 18:58:03 2018	(r329338)
+++ head/stand/libsa/rarp.c	Thu Feb 15 19:49:15 2018	(r329339)
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
 
 
 static ssize_t rarpsend(struct iodesc *, void *, size_t);
-static ssize_t rarprecv(struct iodesc *, void **, void **, time_t);
+static ssize_t rarprecv(struct iodesc *, void **, void **, time_t, void *);
 
 /*
  * Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826).
@@ -99,7 +99,7 @@ rarp_getipaddress(int sock)
 
 	if (sendrecv(d,
 	    rarpsend, &wbuf.data, sizeof(wbuf.data),
-	    rarprecv, &pkt, (void *)&ap) < 0) {
+	    rarprecv, &pkt, (void *)&ap, NULL) < 0) {
 		printf("No response for RARP request\n");
 		return (-1);
 	}
@@ -143,7 +143,8 @@ rarpsend(struct iodesc *d, void *pkt, size_t len)
  * else -1 (and errno == 0)
  */
 static ssize_t
-rarprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft)
+rarprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft,
+    void *extra)
 {
 	ssize_t n;
 	struct ether_arp *ap;

Modified: head/stand/libsa/rpc.c
==============================================================================
--- head/stand/libsa/rpc.c	Thu Feb 15 18:58:03 2018	(r329338)
+++ head/stand/libsa/rpc.c	Thu Feb 15 19:49:15 2018	(r329339)
@@ -97,7 +97,7 @@ struct rpc_reply {
 };
 
 /* Local forwards */
-static	ssize_t recvrpc(struct iodesc *, void **, void **, time_t);
+static	ssize_t recvrpc(struct iodesc *, void **, void **, time_t, void *);
 static	int rpc_getport(struct iodesc *, n_long, n_long);
 
 int rpc_xid;
@@ -167,7 +167,7 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n
 	ptr = NULL;
 	cc = sendrecv(d,
 	    sendudp, send_head, send_tail - send_head,
-	    recvrpc, &ptr, (void **)&reply);
+	    recvrpc, &ptr, (void **)&reply, NULL);
 
 #ifdef RPC_DEBUG
 	if (debug)
@@ -217,7 +217,7 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n
  * Remaining checks are done by callrpc
  */
 static ssize_t
-recvrpc(struct iodesc *d, void **pkt, void **payload, time_t tleft)
+recvrpc(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra)
 {
 	void *ptr;
 	struct rpc_reply *reply;

Modified: head/stand/libsa/tftp.c
==============================================================================
--- head/stand/libsa/tftp.c	Thu Feb 15 18:58:03 2018	(r329338)
+++ head/stand/libsa/tftp.c	Thu Feb 15 19:49:15 2018	(r329339)
@@ -61,7 +61,10 @@ __FBSDID("$FreeBSD$");
 #include "tftp.h"
 
 struct tftp_handle;
+struct tftprecv_extra;
 
+static ssize_t recvtftp(struct iodesc *d, void **pkt, void **payload,
+    time_t tleft, void *recv_extra);
 static int	tftp_open(const char *path, struct open_file *f);
 static int	tftp_close(struct open_file *f);
 static int	tftp_parse_oack(struct tftp_handle *h, char *buf, size_t len);
@@ -70,11 +73,6 @@ static int	tftp_write(struct open_file *f, void *buf, 
 static off_t	tftp_seek(struct open_file *f, off_t offset, int where);
 static int	tftp_set_blksize(struct tftp_handle *h, const char *str);
 static int	tftp_stat(struct open_file *f, struct stat *sb);
-static ssize_t sendrecv_tftp(struct tftp_handle *h,
-    ssize_t (*sproc)(struct iodesc *, void *, size_t),
-    void *sbuf, size_t ssize,
-    ssize_t (*rproc)(struct tftp_handle *h, void **, void **, time_t, unsigned short *),
-    void **, void **, unsigned short *rtype);
 
 struct fs_ops tftp_fsops = {
 	"tftp",
@@ -118,6 +116,11 @@ struct tftp_handle {
 	struct tftphdr	*tftp_hdr;
 };
 
+struct tftprecv_extra {
+	struct tftp_handle	*tftp_handle;
+	unsigned short		 rtype;		/* Received type */
+};
+
 #define	TFTP_MAX_ERRCODE EOPTNEG
 static const int tftperrors[TFTP_MAX_ERRCODE + 1] = {
 	0,			/* ??? */
@@ -178,15 +181,19 @@ tftp_sendack(struct tftp_handle *h)
 }
 
 static ssize_t
-recvtftp(struct tftp_handle *h, void **pkt, void **payload, time_t tleft,
-    unsigned short *rtype)
+recvtftp(struct iodesc *d, void **pkt, void **payload, time_t tleft,
+    void *recv_extra)
 {
-	struct iodesc *d = h->iodesc;
+	struct tftprecv_extra *extra;
+	struct tftp_handle *h;
 	struct tftphdr *t;
+	unsigned short *rtype;
 	void *ptr = NULL;
 	ssize_t len;
 
 	errno = 0;
+	extra = (struct tftprecv_extra *)recv_extra;
+	h = extra->tftp_handle;
 
 	len = readudp(d, &ptr, (void **)&t, tleft);
 
@@ -195,7 +202,7 @@ recvtftp(struct tftp_handle *h, void **pkt, void **pay
 		return (-1);
 	}
 
-	*rtype = ntohs(t->th_opcode);
+	extra->rtype = ntohs(t->th_opcode);
 	switch (ntohs(t->th_opcode)) {
 	case DATA: {
 		int got;
@@ -282,6 +289,7 @@ tftp_makereq(struct tftp_handle *h)
 		struct tftphdr  t;
 		u_char space[FNAME_SIZE + 6];
 	} __packed __aligned(4) wbuf;
+	struct tftprecv_extra recv_extra;
 	char           *wtail;
 	int             l;
 	ssize_t         res;
@@ -289,7 +297,6 @@ tftp_makereq(struct tftp_handle *h)
 	struct tftphdr *t;
 	char *tftp_blksize = NULL;
 	int blksize_l;
-	unsigned short rtype = 0;
 
 	/*
 	 * Allow overriding default TFTP block size by setting
@@ -334,8 +341,9 @@ tftp_makereq(struct tftp_handle *h)
 	h->validsize = 0;
 
 	pkt = NULL;
-	res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
-		       &recvtftp, &pkt, (void **)&t, &rtype);
+	recv_extra.tftp_handle = h;
+	res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
+		       (void *)&recvtftp, &pkt, (void **)&t, &recv_extra);
 	if (res == -1) {
 		free(pkt);
 		return (errno);
@@ -345,13 +353,13 @@ tftp_makereq(struct tftp_handle *h)
 	h->pkt = pkt;
 	h->tftp_hdr = t;
 
-	if (rtype == OACK)
+	if (recv_extra.rtype == OACK)
 		return (tftp_getnextblock(h));
 
 	/* Server ignored our blksize request, revert to TFTP default. */
 	h->tftp_blksize = SEGSIZE;
 
-	switch (rtype) {
+	switch (recv_extra.rtype) {
 		case DATA: {
 			h->currblock = 1;
 			h->validsize = res;
@@ -377,11 +385,11 @@ tftp_getnextblock(struct tftp_handle *h)
 		u_char header[HEADER_SIZE];
 		struct tftphdr t;
 	} __packed __aligned(4) wbuf;
+	struct tftprecv_extra recv_extra;
 	char           *wtail;
 	int             res;
 	void *pkt;
 	struct tftphdr *t;
-	unsigned short rtype = 0;
 	wbuf.t.th_opcode = htons((u_short) ACK);
 	wtail = (char *) &wbuf.t.th_block;
 	wbuf.t.th_block = htons((u_short) h->currblock);
@@ -390,8 +398,9 @@ tftp_getnextblock(struct tftp_handle *h)
 	h->iodesc->xid = h->currblock + 1;	/* expected block */
 
 	pkt = NULL;
-	res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
-		       &recvtftp, &pkt, (void **)&t, &rtype);
+	recv_extra.tftp_handle = h;
+	res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
+		       (void *)&recvtftp, &pkt, (void **)&t, &recv_extra);
 
 	if (res == -1) {		/* 0 is OK! */
 		free(pkt);
@@ -603,67 +612,6 @@ tftp_seek(struct open_file *f, off_t offset, int where
 		return (-1);
 	}
 	return (tftpfile->off);
-}
-
-static ssize_t
-sendrecv_tftp(struct tftp_handle *h,
-    ssize_t (*sproc)(struct iodesc *, void *, size_t),
-    void *sbuf, size_t ssize,
-    ssize_t (*rproc)(struct tftp_handle *, void **, void **, time_t,
-    unsigned short *),
-    void **pkt, void **payload, unsigned short *rtype)
-{
-	struct iodesc *d = h->iodesc;
-	ssize_t cc;
-	time_t t, t1, tleft;
-
-#ifdef TFTP_DEBUG
-	if (debug)
-		printf("sendrecv: called\n");
-#endif
-
-	tleft = MINTMO;
-	t = t1 = getsecs();
-	for (;;) {
-		if ((getsecs() - t) > MAXTMO) {
-			errno = ETIMEDOUT;
-			return -1;
-		}
-
-		cc = (*sproc)(d, sbuf, ssize);
-		if (cc != -1 && cc < ssize)
-			panic("sendrecv: short write! (%zd < %zu)",
-			    cc, ssize);
-
-		if (cc == -1) {
-			/* Error on transmit; wait before retrying */
-			while ((getsecs() - t1) < tleft);
-			t1 = getsecs();
-			continue;
-		}
-
-		t = t1 = getsecs();
-recvnext:
-		if ((getsecs() - t) > MAXTMO) {
-			errno = ETIMEDOUT;
-			return -1;
-		}
-		/* Try to get a packet and process it. */
-		cc = (*rproc)(h, pkt, payload, tleft, rtype);
-		/* Return on data, EOF or real error. */
-		if (cc != -1 || (errno != 0 && errno != ETIMEDOUT))
-			return (cc);
-		if ((getsecs() - t1) < tleft) {
-		    goto recvnext;
-		}
-
-		/* Timed out or didn't get the packet we're waiting for */
-		tleft += MINTMO;
-		if (tleft > (2 * MINTMO)) {
-			tleft = (2 * MINTMO);
-		}
-		t1 = getsecs();
-	}
 }
 
 static int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802151949.w1FJnFS4044411>