Пример #1
0
/*
 * Grab a single command sequence off the socket, and enqueue
 * it in the incoming event queue in a seperate struct.
 */
faim_export int aim_get_command(aim_session_t *sess, aim_conn_t *conn)
{
    fu8_t flaphdr_raw[6];
    aim_bstream_t flaphdr;
    aim_frame_t *newrx;
    fu16_t payloadlen;

    if (!sess || !conn)
        return 0;

    if (conn->fd == -1)
        return -1; /* its a aim_conn_close()'d connection */

    if (conn->fd < 3)  /* can happen when people abuse the interface */
        return 0;

    if (conn->status & AIM_CONN_STATUS_INPROGRESS)
        return aim_conn_completeconnect(sess, conn);

    /*
     * Rendezvous (client-client) connections do not speak
     * FLAP, so this function will break on them.
     */
    if (conn->type == AIM_CONN_TYPE_RENDEZVOUS)
        return aim_get_command_rendezvous(sess, conn);
    else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
        faimdprintf(sess, 0, "AIM_CONN_TYPE_RENDEZVOUS_OUT on fd %d\n", conn->fd);
        return 0;
    }

    aim_bstream_init(&flaphdr, flaphdr_raw, sizeof(flaphdr_raw));

    /*
     * Read FLAP header.  Six bytes:
     *
     *   0 char  -- Always 0x2a
     *   1 char  -- Channel ID.  Usually 2 -- 1 and 4 are used during login.
     *   2 short -- Sequence number
     *   4 short -- Number of data bytes that follow.
     */
    if (aim_bstream_recv(&flaphdr, conn->fd, 6) < 6) {
        aim_conn_close(conn);
        return -1;
    }

    aim_bstream_rewind(&flaphdr);

    /*
     * This shouldn't happen unless the socket breaks, the server breaks,
     * or we break.  We must handle it just in case.
     */
    if (aimbs_get8(&flaphdr) != 0x2a) {
        fu8_t start;

        aim_bstream_rewind(&flaphdr);
        start = aimbs_get8(&flaphdr);
        faimdprintf(sess, 0, "FLAP framing disrupted (0x%02x)", start);
        aim_conn_close(conn);
        return -1;
    }

    /* allocate a new struct */
    if (!(newrx = (aim_frame_t *)malloc(sizeof(aim_frame_t))))
        return -1;
    memset(newrx, 0, sizeof(aim_frame_t));

    /* we're doing FLAP if we're here */
    newrx->hdrtype = AIM_FRAMETYPE_FLAP;

    newrx->hdr.flap.type = aimbs_get8(&flaphdr);
    newrx->hdr.flap.seqnum = aimbs_get16(&flaphdr);
    payloadlen = aimbs_get16(&flaphdr);

    newrx->nofree = 0; /* free by default */

    if (payloadlen) {
        fu8_t *payload = NULL;

        if (!(payload = (fu8_t *) malloc(payloadlen))) {
            aim_frame_destroy(newrx);
            return -1;
        }

        aim_bstream_init(&newrx->data, payload, payloadlen);

        /* read the payload */
        if (aim_bstream_recv(&newrx->data, conn->fd, payloadlen) < payloadlen) {
            free(payload);
            aim_frame_destroy(newrx);
            aim_conn_close(conn);
            return -1;
        }
    } else
        aim_bstream_init(&newrx->data, NULL, 0);


    aim_bstream_rewind(&newrx->data);

    newrx->conn = conn;

    newrx->next = NULL;  /* this will always be at the bottom */

    if (!sess->queue_incoming)
        sess->queue_incoming = newrx;
    else {
        aim_frame_t *cur;

        for (cur = sess->queue_incoming; cur->next; cur = cur->next)
            ;
        cur->next = newrx;
    }

    newrx->conn->lastactivity = time(NULL);

    return 0;
}
Пример #2
0
/*
 * Grab a single command sequence off the socket, and enqueue it in the incoming event queue 
 * in a separate struct.
 */
faim_export int aim_get_command(aim_session_t *sess, aim_conn_t *conn)
{
	aim_frame_t *newrx;
	fu16_t payloadlen;

	if (!sess || !conn)
		return -EINVAL;

	if (conn->fd == -1)
		return -1;	/* it's an aim_conn_close()'d connection */

	if (conn->fd < 3)	/* can happen when people abuse the interface */
		return -1;

	if (conn->status & AIM_CONN_STATUS_INPROGRESS)
		return aim_conn_completeconnect(sess, conn);

	if (!(newrx = (aim_frame_t *)calloc(sizeof(aim_frame_t), 1)))
		return -ENOMEM;

	/*
	 * Rendezvous (client to client) connections do not speak FLAP, so this 
	 * function will break on them.
	 */
	if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
		int ret = aim_get_command_rendezvous(sess, conn, newrx);

		if (ret < 0) {
			free(newrx);
			return -1;
		}

		payloadlen = ret;
	} else if (conn->type == AIM_CONN_TYPE_LISTENER) {
		faimdprintf(sess, 0, "AIM_CONN_TYPE_LISTENER on fd %d\n",
			conn->fd);
		free(newrx);
		return -1;
	} else
		payloadlen = aim_get_command_flap(sess, conn, newrx);

	newrx->nofree = 0;	/* free by default */

	if (payloadlen) {
		fu8_t *payload = NULL;

		if (!(payload = (fu8_t *)malloc(payloadlen))) {
			aim_frame_destroy(newrx);
			return -1;
		}

		aim_bstream_init(&newrx->data, payload, payloadlen);

		/* read the payload */
		if (aim_bstream_recv(&newrx->data, conn->fd,
				payloadlen) < payloadlen) {
			aim_frame_destroy(newrx);	/* free's payload */
			aim_conn_close(conn);
			return -1;
		}
	} else
		aim_bstream_init(&newrx->data, NULL, 0);

	aim_bstream_rewind(&newrx->data);

	newrx->conn = conn;

	newrx->next = NULL;	/* this will always be at the bottom */

	if (!sess->queue_incoming)
		sess->queue_incoming = newrx;
	else {
		aim_frame_t *cur;

		for (cur = sess->queue_incoming; cur->next; cur = cur->next) ;
		cur->next = newrx;
	}

	newrx->conn->lastactivity = time(NULL);

	return 0;
}