PERFORCE change 125233 for review
Fredrik Lindberg
fli at FreeBSD.org
Thu Aug 16 12:45:04 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125233
Change 125233 by fli at 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);
More information about the p4-projects
mailing list