Example #1
0
static void udps_send_user(TCPIPS* tcpips, IP* src, IO* io, HANDLE handle)
{
    IO* user_io;
    unsigned int offset, size;
    UDP_STACK* udp_stack;
    UDP_HANDLE* uh;
    UDP_HEADER* hdr = io_data(io);

    uh = so_get(&tcpips->udps.handles, handle);
    for (offset = sizeof(UDP_HEADER); uh->head && offset < io->data_size; offset += size)
    {
        user_io = udps_peek_head(tcpips, uh);
        udp_stack = io_push(user_io, sizeof(UDP_STACK));
        udp_stack->remote_addr.u32.ip = src->u32.ip;
        udp_stack->remote_port = be2short(hdr->src_port_be);

        size = io_get_free(user_io);
        if (size > io->data_size - offset)
            size = io->data_size - offset;
        memcpy(io_data(user_io), (uint8_t*)io_data(io) + offset, size);
        user_io->data_size = size;
        io_complete(uh->process, HAL_IO_CMD(HAL_UDP, IPC_READ), handle, user_io);
    }
#if (UDP_DEBUG)
    if (offset < io->data_size)
        printf("UDP: %d byte(s) dropped\n", io->data_size - offset);
#endif //UDP_DEBUG
}
Example #2
0
File: io.c Project: mbeck-/fdm
/* Handle io after polling. */
int
io_after_poll(struct io *io, struct pollfd *pfd)
{
    /* Ignore NULL ios. */
    if (io == NULL)
        return (1);

    IO_DEBUG(io, "poll out: 0x%03x", pfd->revents);

    /* Close on POLLERR or POLLNVAL hard. */
    if (pfd->revents & (POLLERR|POLLNVAL)) {
        io->flags |= IOF_CLOSED;
        return (0);
    }
    /* Close on POLLHUP but only if there is nothing to read. */
    if (pfd->revents & POLLHUP && (pfd->revents & POLLIN) == 0) {
        io->flags |= IOF_CLOSED;
        return (0);
    }

    /* Check for repeated read/write. */
    if ((io->flags & (IOF_NEEDPUSH|IOF_NEEDFILL)) != 0) {
        /*
         * If a repeated read/write is necessary, the socket must be
         * ready for both reading and writing
         */
        if (pfd->revents & (POLLOUT|POLLIN)) {
            if (io->flags & IOF_NEEDPUSH) {
                switch (io_push(io)) {
                case 0:
                    io->flags |= IOF_CLOSED;
                    return (0);
                case -1:
                    return (-1);
                }
            }
            if (io->flags & IOF_NEEDFILL) {
                switch (io_fill(io)) {
                case 0:
                    io->flags |= IOF_CLOSED;
                    return (0);
                case -1:
                    return (-1);
                }
            }
        }
        return (1);
    }

    /* Otherwise try to read and write. */
    if (io->wr != NULL && pfd->revents & POLLOUT) {
        switch (io_push(io)) {
        case 0:
            io->flags |= IOF_CLOSED;
            return (0);
        case -1:
            return (-1);
        }
    }
    if (io->rd != NULL && pfd->revents & POLLIN) {
        switch (io_fill(io)) {
        case 0:
            io->flags |= IOF_CLOSED;
            return (0);
        case -1:
            return (-1);
        }
    }

    return (1);
}