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>