Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Aug 2007 19:45:03 GMT
From:      Fredrik Lindberg <fli@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 125233 for review
Message-ID:  <200708161945.l7GJj3b9011150@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125233

Change 125233 by fli@fli_nexus on 2007/08/16 19:44:52

	- Fix LOCAL_CREDS which I somehow broke.
	- Make the message read more robust and properly handle
	  message that are written using multiple write() calls.
	- Fix code that simply was broken.
	- Follow dbr_ident_add() changes.
	- Some minor whitespace and debugging fixes.

Affected files ...

.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/clisrv.c#5 edit

Differences ...

==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/clisrv.c#5 (text+ko) ====

@@ -25,6 +25,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/select.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/ucred.h>
@@ -215,7 +216,7 @@
 	struct clisrv *cs;
 	struct cs_client *csc;
 	struct md_glob *g;
-	int sock;
+	int sock, so, error;
 	ev_arg eva;
 
 	cs = arg.ptr;
@@ -230,6 +231,12 @@
 		goto out;
 	}
 
+	so = 1;
+	error = setsockopt(sock, 0, LOCAL_CREDS, &so, sizeof(so));
+	if (error != 0)
+		logger(LOG_ERR, "setsockopt LOCAL_CREDS failed: %s",
+		    strerror(errno));
+
 	csc = obj_alloc(OBJ_CSC);
 	MDNS_INIT_SET(csc, csc_magic);
 	MTX_INIT(csc, csc_mtx, NULL);
@@ -305,9 +312,13 @@
 	struct cmsghdr *cmptr;
 	struct sockcred *cred;
 	struct mipc_head *mih;
-	int n, sock, error, len;
+	int n, sock, error;
+	char *p;
+	size_t rlen, len, len2;
 	struct msghdr msg;
 	struct iovec iov[1];
+	fd_set rfd;
+	struct timeval tv;
 	char control[CMSG_LEN(SOCKCREDSIZE(1)) + sizeof(struct cmsghdr)];
 	char buf[MIPC_MAXPLEN];
 
@@ -324,10 +335,11 @@
 	msg.msg_control = control;
 	msg.msg_controllen = sizeof(control);
 	msg.msg_flags = 0;
-	iov[0].iov_base = buf + sizeof(struct mipc_head);
+	iov[0].iov_base = buf;
+	iov[0].iov_len = sizeof(struct mipc_head);
 
 	for (;;) {
-		n = read(sock, buf, sizeof(struct mipc_head));
+		n = recvmsg(sock, &msg, 0);
 		if (n < (signed int)sizeof(struct mipc_head))
 			break;
 
@@ -335,14 +347,6 @@
 		if (mih->mih_ver != MIPC_VERSION)
 			continue;
 
-		len = mih->mih_msglen > MIPC_MAXPLEN ?
-		    MIPC_MAXPLEN : mih->mih_msglen;
-		iov[0].iov_len = len - sizeof(struct mipc_head);
-
-		n = recvmsg(sock, &msg, 0);
-		if ((unsigned int)n != iov[0].iov_len)
-			continue;
-
 		/* Check credentials */
 		cmptr = CMSG_FIRSTHDR(&msg);
 		if (cmptr != NULL) {
@@ -353,11 +357,42 @@
 			}
 		}
 
+		len = mih->mih_msglen > MIPC_MAXPLEN ?
+		    MIPC_MAXPLEN : mih->mih_msglen;
+
+		rlen = len - sizeof(struct mipc_head);
+		p = buf + sizeof(struct mipc_head);
+
+		tv.tv_sec = 0;
+		tv.tv_usec = 500000;
+		len2 = 0;
+
+		do {
+			n = read(sock, p, rlen);
+			if (n > 0) {
+				rlen -= n;
+				p += n;
+				len2 += n;
+			}
+			else if (errno == EAGAIN) {
+				FD_ZERO(&rfd);
+				FD_SET(sock, &rfd);
+				error = select(sock + 1, &rfd, NULL, NULL, &tv);
+				if (error == 0)
+					break;
+			}
+			else {
+				break;
+			}
+		} while (rlen > 0);
+
+		if (rlen > 0)
+			break;
+
 		dprintf(DEBUG_CS, "Received packet on UNIX pipe csc=%x, "
 		    "len=%d, suser=%d, sock=%d", csc, n, csc->csc_suser, sock);
 
-		n += sizeof(struct mipc_head);
-		error = cp_parse(csc, buf, n, csc->csc_suser);
+		error = cp_parse(csc, buf, len, csc->csc_suser);
 		if (error != 0)
 			dprintf(DEBUG_CS, "Failed to parse packet csc=%x", csc);
 	}
@@ -425,8 +460,8 @@
 	
 	mih = (struct mipc_head *)buf;
 
-	dprintf(DEBUG_CS, "Header ver=%d, msgtype=%d",
-	    mih->mih_ver, mih->mih_msgtype);
+	dprintf(DEBUG_CS, "Header ver=%d, msgtype=%d, msglen=%d",
+	    mih->mih_ver, mih->mih_msgtype, mih->mih_msglen);
 
 	if (mih->mih_ver != MIPC_VERSION) {
 		error = MIE_IVAL;
@@ -486,7 +521,7 @@
 	memcpy(name, wp, miq->miq_len * sizeof(wchar_t));
 	name[miq->miq_len] = L'\0';
 
-	nam = mdns_name_encode(name, MDNS_RECORD_LEN, MDNS_ENC_AUTO); 
+	nam = mdns_name_encode(name, MDNS_RECORD_LEN, MDNS_ENC_AUTO);
 	if (nam == NULL)
 		return (MIE_IVAL);
 
@@ -648,7 +683,7 @@
 	struct md_glob *g;
 	struct md_if *mif;
 	char *ident, *p;
-	int error = 0;
+	int flags, error = 0;
 
 	g = csc->csc_serv->cs_glob;
 
@@ -662,7 +697,7 @@
 	if (mii->mii_ifidx > g->g_ifs_max)
 		return (MIE_IVAL);
 
-	if (mii->mii_len > len)
+	if (mii->mii_len > len || mii->mii_len == 0)
 		return (MIE_IVAL);
 
 	ident = malloc(mii->mii_len + 1);
@@ -674,6 +709,10 @@
 	dprintf(DEBUG_CS, "Request to add resource identifier %s, ifidx=%d "
 	    "csc=%x", ident, mii->mii_ifidx, csc);
 
+	flags = 0;
+	if (mii->mii_shared)
+		flags |= DBI_SHARED;
+
 	RW_RLOCK(g, g_lock);
 
 	/*
@@ -687,12 +726,12 @@
 			free(ident);
 			return (MIE_IVAL);
 		}
-		error = dbr_ident_add(&mif->mif_dbr, ident);
+		error = dbr_ident_add(&mif->mif_dbr, ident, flags);
 	}
 	else {
 		/* We ignore errors in this case */
 		TAILQ_FOREACH(mif, &g->g_ifs_head, mif_next) {
-			dbr_ident_add(&mif->mif_dbr, ident);
+			dbr_ident_add(&mif->mif_dbr, ident, flags);
 		}
 	}
 
@@ -772,26 +811,29 @@
 parse_dbi_name(char *buf, size_t len, struct mipc_dbi_name **miin, char **ident,
     wchar_t **name)
 {
-	char *p;
+	char *p, *identp;
 	struct mipc_dbi_name *miin2;
+	wchar_t *namp;
 
 	if (len < sizeof(struct mipc_dbi_name))
 		return (MIE_IVAL);
 
 	*miin = (struct mipc_dbi_name *)buf;
+	miin2 = *miin;
+
 	len -= sizeof(struct mipc_dbi_name);
 	p = buf + sizeof(struct mipc_dbi_name);
 
-	miin2 = *miin;
-
 	if (len < miin2->miin_ilen)
 		return (MIE_IVAL);
 
-	*ident = malloc(miin2->miin_ilen + 1);
-	if (*ident == NULL)
+	identp = malloc(miin2->miin_ilen + 1);
+	if (identp == NULL)
 		return (MIE_INTE);
-	memcpy(*ident, p, miin2->miin_ilen);
-	*ident[miin2->miin_ilen] = '\0';
+	memcpy(identp, p, miin2->miin_ilen);
+	identp[miin2->miin_ilen] = '\0';
+	*ident = identp;	
+
 	p += miin2->miin_ilen;
 	len -= miin2->miin_ilen;
 
@@ -800,13 +842,15 @@
 		return (MIE_IVAL);
 	}
 
-	*name = malloc((miin2->miin_len + 1) * sizeof(wchar_t));
-	if (*name == NULL) {
+	namp = malloc((miin2->miin_len + 1) * sizeof(wchar_t));
+	if (namp == NULL) {
 		free(*ident);
 		return (MIE_IVAL);
 	}
-	memcpy(*name, p, miin2->miin_len * sizeof(wchar_t));
-	*name[miin2->miin_len] = L'\0';
+
+	memcpy(namp, p, miin2->miin_len * sizeof(wchar_t));
+	namp[miin2->miin_len] = L'\0';
+	*name = namp;
 
 	return (0);
 }
@@ -898,13 +942,13 @@
 		mif = g->g_ifs[miin->miin_ifidx];
 		if (mif == NULL)
 			goto error;
-		error = dbr_name_add(&mif->mif_dbr, ident, name);
+		error = dbr_name_del(&mif->mif_dbr, ident, name);
 		if (error != 0)
 			retval = MIE_EXISTS;
 	}
 	else {
 		TAILQ_FOREACH(mif, &g->g_ifs_head, mif_next) {
-			dbr_name_add(&mif->mif_dbr, ident, name);
+			dbr_name_del(&mif->mif_dbr, ident, name);
 		}
 	}
 
@@ -1032,7 +1076,8 @@
     char **ident, wchar_t **res, char **resptr)
 {
 	struct mipc_dbi_res_set *mirs2;
-	char *p;
+	char *p, *identp, *tmp;
+	wchar_t *res2;
 
 	if (len < sizeof(struct mipc_dbi_res_set))
 		return (MIE_IVAL);
@@ -1046,11 +1091,12 @@
 	if (len < mirs2->mirs_ilen)
 		return (MIE_IVAL);
 
-	*ident = malloc(mirs2->mirs_ilen + 1);
-	if (*ident == NULL)
+	identp = malloc(mirs2->mirs_ilen + 1);
+	if (identp == NULL)
 		return (MIE_INTE);
-	memcpy(*ident, p, mirs2->mirs_ilen);
-	*ident[mirs2->mirs_ilen] = '\0';
+	memcpy(identp, p, mirs2->mirs_ilen);
+	identp[mirs2->mirs_ilen] = '\0';
+	*ident = identp;
 	p += mirs2->mirs_ilen;
 	len -= mirs2->mirs_ilen;
 
@@ -1063,13 +1109,14 @@
 			return (MIE_IVAL);
 		}
 
-		*resptr = malloc(mirs2->mirs_rlen + 1);
-		if (*resptr == NULL) {
+		tmp = malloc(mirs2->mirs_rlen + 1);
+		if (tmp == NULL) {
 			free(*ident);
 			return (MIE_IVAL);
 		}
-		memcpy(*resptr, p, mirs2->mirs_rlen);
-		*resptr[mirs2->mirs_rlen] = '\0';
+		memcpy(tmp, p, mirs2->mirs_rlen);
+		tmp[mirs2->mirs_rlen] = '\0';
+		*resptr = tmp;
 	}
 	else {
 		if (len < (mirs2->mirs_rlen * sizeof(wchar_t))) {
@@ -1077,13 +1124,14 @@
 			return (MIE_IVAL);
 		}
 
-		*res = malloc((mirs2->mirs_rlen + 1) * sizeof(wchar_t));
-		if (*res == NULL) {
+		res2 = malloc((mirs2->mirs_rlen + 1) * sizeof(wchar_t));
+		if (res2 == NULL) {
 			free(*ident);
 			return (MIE_INTE);
 		}
-		memcpy(*res, p, mirs2->mirs_rlen * sizeof(wchar_t));
-		*res[mirs2->mirs_rlen] = L'\0';
+		memcpy(res2, p, mirs2->mirs_rlen * sizeof(wchar_t));
+		res2[mirs2->mirs_rlen] = L'\0';
+		*res = res2;
 	}
 
 	return (0);



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