コード例 #1
0
ファイル: connection.c プロジェクト: SylvestreG/bitrig
void
conn_dispatch(int fd, short event, void *arg)
{
	struct connection *c = arg;
	ssize_t n;

	if (!(event & EV_READ)) {
		log_debug("spurious read call");
		return;
	}
	if ((n = pdu_read(c)) == -1) {
		if (errno == EAGAIN || errno == ENOBUFS ||
		    errno == EINTR)	/* try later */
			return;
		log_warn("pdu_read");
		conn_fsm(c, CONN_EV_FAIL);
		return;
	}
	if (n == 0) {    /* connection closed */
		conn_fsm(c, CONN_EV_CLOSED);
		return;
	}

	pdu_parse(c);
}
コード例 #2
0
ファイル: pdu.c プロジェクト: adonis1104/freebsd
void
pdu_receive(struct pdu *pdu)
{
	size_t len, padding;
	char dummy[4];

#ifdef ICL_KERNEL_PROXY
	if (pdu->pdu_connection->conn_conf.isc_iser != 0)
		return (pdu_receive_proxy(pdu));
#endif

	assert(pdu->pdu_connection->conn_conf.isc_iser == 0);

	pdu_read(pdu->pdu_connection->conn_socket,
	    (char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs));

	len = pdu_ahs_length(pdu);
	if (len > 0)
		log_errx(1, "protocol error: non-empty AHS");

	len = pdu_data_segment_length(pdu);
	if (len > 0) {
		if (len > ISCSI_MAX_DATA_SEGMENT_LENGTH) {
			log_errx(1, "protocol error: received PDU "
			    "with DataSegmentLength exceeding %d",
			    ISCSI_MAX_DATA_SEGMENT_LENGTH);
		}

		pdu->pdu_data_len = len;
		pdu->pdu_data = malloc(len);
		if (pdu->pdu_data == NULL)
			log_err(1, "malloc");

		pdu_read(pdu->pdu_connection->conn_socket,
		    (char *)pdu->pdu_data, pdu->pdu_data_len);

		padding = pdu_padding(pdu);
		if (padding != 0) {
			assert(padding < sizeof(dummy));
			pdu_read(pdu->pdu_connection->conn_socket,
			    (char *)dummy, padding);
		}
	}
}
コード例 #3
0
static int
p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
             va_list ap)
{
    const char *ptr;
    int errcode = 0;

    for (ptr = fmt; *ptr; ptr++) {
        switch (*ptr) {
        case 'b': {
            int8_t *val = va_arg(ap, int8_t *);
            if (pdu_read(pdu, val, sizeof(*val))) {
                errcode = -EFAULT;
                break;
            }
        }
        break;
        case 'w': {
            int16_t *val = va_arg(ap, int16_t *);
            __le16 le_val;
            if (pdu_read(pdu, &le_val, sizeof(le_val))) {
                errcode = -EFAULT;
                break;
            }
            *val = le16_to_cpu(le_val);
        }
        break;
        case 'd': {
            int32_t *val = va_arg(ap, int32_t *);
            __le32 le_val;
            if (pdu_read(pdu, &le_val, sizeof(le_val))) {
                errcode = -EFAULT;
                break;
            }
            *val = le32_to_cpu(le_val);
        }
        break;
        case 'q': {
            int64_t *val = va_arg(ap, int64_t *);
            __le64 le_val;
            if (pdu_read(pdu, &le_val, sizeof(le_val))) {
                errcode = -EFAULT;
                break;
            }
            *val = le64_to_cpu(le_val);
        }
        break;
        case 's': {
            char **sptr = va_arg(ap, char **);
            int16_t len;
            int size;

            errcode = p9pdu_readf(pdu, proto_version,
                                  "w", &len);
            if (errcode)
                break;

            size = MAX(len, 0);

            *sptr = kmalloc(size + 1, GFP_KERNEL);
            if (*sptr == NULL) {
                errcode = -EFAULT;
                break;
            }
            if (pdu_read(pdu, *sptr, size)) {
                errcode = -EFAULT;
                kfree(*sptr);
                *sptr = NULL;
            } else
                (*sptr)[size] = 0;
        }
        break;
        case 'Q': {
            struct p9_qid *qid =
                va_arg(ap, struct p9_qid *);

            errcode = p9pdu_readf(pdu, proto_version, "bdq",
                                  &qid->type, &qid->version,
                                  &qid->path);
        }
        break;
        case 'S': {
            struct p9_wstat *stbuf =
                va_arg(ap, struct p9_wstat *);

            memset(stbuf, 0, sizeof(struct p9_wstat));
            stbuf->n_uid = stbuf->n_gid = stbuf->n_muid =
                                              -1;
            errcode =
                p9pdu_readf(pdu, proto_version,
                            "wwdQdddqssss?sddd",
                            &stbuf->size, &stbuf->type,
                            &stbuf->dev, &stbuf->qid,
                            &stbuf->mode, &stbuf->atime,
                            &stbuf->mtime, &stbuf->length,
                            &stbuf->name, &stbuf->uid,
                            &stbuf->gid, &stbuf->muid,
                            &stbuf->extension,
                            &stbuf->n_uid, &stbuf->n_gid,
                            &stbuf->n_muid);
            if (errcode)
                p9stat_free(stbuf);
        }
        break;
        case 'D': {
            int32_t *count = va_arg(ap, int32_t *);
            void **data = va_arg(ap, void **);

            errcode =
                p9pdu_readf(pdu, proto_version, "d", count);
            if (!errcode) {
                *count =
                    MIN(*count,
                        pdu->size - pdu->offset);
                *data = &pdu->sdata[pdu->offset];
            }
        }
        break;
        case 'T': {
            int16_t *nwname = va_arg(ap, int16_t *);
            char ***wnames = va_arg(ap, char ***);

            errcode = p9pdu_readf(pdu, proto_version,
                                  "w", nwname);
            if (!errcode) {
                *wnames =
                    kmalloc(sizeof(char *) * *nwname,
                            GFP_KERNEL);
                if (!*wnames)
                    errcode = -ENOMEM;
            }

            if (!errcode) {
                int i;

                for (i = 0; i < *nwname; i++) {
                    errcode =
                        p9pdu_readf(pdu,
                                    proto_version,
                                    "s",
                                    &(*wnames)[i]);
                    if (errcode)
                        break;
                }
            }

            if (errcode) {
                if (*wnames) {
                    int i;

                    for (i = 0; i < *nwname; i++)
                        kfree((*wnames)[i]);
                }
                kfree(*wnames);
                *wnames = NULL;
            }
        }
        break;
        case 'R': {
            int16_t *nwqid = va_arg(ap, int16_t *);
            struct p9_qid **wqids =
                va_arg(ap, struct p9_qid **);

            *wqids = NULL;

            errcode =
                p9pdu_readf(pdu, proto_version, "w", nwqid);
            if (!errcode) {
                *wqids =
                    kmalloc(*nwqid *
                            sizeof(struct p9_qid),
                            GFP_KERNEL);
                if (*wqids == NULL)
                    errcode = -ENOMEM;
            }

            if (!errcode) {
                int i;

                for (i = 0; i < *nwqid; i++) {
                    errcode =
                        p9pdu_readf(pdu,
                                    proto_version,
                                    "Q",
                                    &(*wqids)[i]);
                    if (errcode)
                        break;
                }
            }

            if (errcode) {
                kfree(*wqids);
                *wqids = NULL;
            }
        }
        break;
        case '?':
            if ((proto_version != p9_proto_2000u) &&
                    (proto_version != p9_proto_2000L))
                return 0;
            break;
        default:
            BUG();
            break;
        }

        if (errcode)
            break;
    }

    return errcode;
}