예제 #1
0
struct fwtcp *
fwtcp_create(struct fwspec *fwspec)
{
    struct fwtcp *fwtcp;
    SOCKET lsock;
    int status;
    err_t error;

    lsock = proxy_bound_socket(fwspec->sdom, fwspec->stype, &fwspec->src.sa);
    if (lsock == INVALID_SOCKET) {
        perror("socket");
        return NULL;
    }

    fwtcp = (struct fwtcp *)malloc(sizeof(*fwtcp));
    if (fwtcp == NULL) {
        closesocket(lsock);
        return NULL;
    }

    fwtcp->pmhdl.callback = fwtcp_pmgr_listen;
    fwtcp->pmhdl.data = (void *)fwtcp;
    fwtcp->pmhdl.slot = -1;

    fwtcp->sock = lsock;
    fwtcp->fwspec = *fwspec;    /* struct copy */

    error = sys_mbox_new(&fwtcp->connmbox, 16);
    if (error != ERR_OK) {
        closesocket(lsock);
        free(fwtcp);
        return (NULL);
    }

#define CALLBACK_MSG(MSG, FUNC)                         \
    do {                                                \
        fwtcp->MSG.type = TCPIP_MSG_CALLBACK_STATIC;    \
        fwtcp->MSG.sem = NULL;                          \
        fwtcp->MSG.msg.cb.function = FUNC;              \
        fwtcp->MSG.msg.cb.ctx = (void *)fwtcp;          \
    } while (0)

    CALLBACK_MSG(msg_connect, fwtcp_pcb_connect);
    CALLBACK_MSG(msg_delete,  fwtcp_pcb_delete);

#undef CALLBACK_MSG

    status = pollmgr_add(&fwtcp->pmhdl, fwtcp->sock, POLLIN);
    if (status < 0) {
        sys_mbox_free(&fwtcp->connmbox);
        closesocket(lsock);
        free(fwtcp);
        return NULL;
    }

    fwtcp->next = fwtcp_list;
    fwtcp_list = fwtcp;

    return fwtcp;
}
예제 #2
0
struct fwudp *
fwudp_create(struct fwspec *fwspec)
{
    struct fwudp *fwudp;
    SOCKET sock;
    int status;

    sock = proxy_bound_socket(fwspec->sdom, fwspec->stype, &fwspec->src.sa);
    if (sock == INVALID_SOCKET) {
        perror("socket");
        return NULL;
    }

    fwudp = (struct fwudp *)malloc(sizeof(*fwudp));
    if (fwudp == NULL) {
        closesocket(sock);
        return NULL;
    }

    fwudp->pmhdl.callback = fwudp_pmgr_pump;
    fwudp->pmhdl.data = (void *)fwudp;
    fwudp->pmhdl.slot = -1;

    fwudp->sock = sock;
    fwudp->fwspec = *fwspec;    /* struct copy */

    /* XXX */
    if (fwspec->sdom == PF_INET) {
        struct sockaddr_in *dst4 = &fwspec->dst.sin;
        memcpy(&fwudp->dst_addr.ip4, &dst4->sin_addr, sizeof(ip_addr_t));
        fwudp->dst_port = htons(dst4->sin_port);
    }
    else { /* PF_INET6 */
        struct sockaddr_in6 *dst6 = &fwspec->dst.sin6;
        memcpy(&fwudp->dst_addr.ip6, &dst6->sin6_addr, sizeof(ip6_addr_t));
        fwudp->dst_port = htons(dst6->sin6_port);
    }

    fwudp->inbuf.bufsize = 256; /* elements  */
    fwudp->inbuf.buf
        = (struct fwudp_dgram *)calloc(fwudp->inbuf.bufsize,
                                       sizeof(struct fwudp_dgram));
    if (fwudp->inbuf.buf == NULL) {
        closesocket(sock);
        free(fwudp);
        return (NULL);
    }
    fwudp->inbuf.vacant = 0;
    fwudp->inbuf.unsent = 0;

#define CALLBACK_MSG(MSG, FUNC)                         \
    do {                                                \
        fwudp->MSG.type = TCPIP_MSG_CALLBACK_STATIC;    \
        fwudp->MSG.sem = NULL;                          \
        fwudp->MSG.msg.cb.function = FUNC;              \
        fwudp->MSG.msg.cb.ctx = (void *)fwudp;          \
    } while (0)

    CALLBACK_MSG(msg_send, fwudp_pcb_send);
    CALLBACK_MSG(msg_delete, fwudp_pcb_delete);

#undef CALLBACK_MSG

    status = pollmgr_add(&fwudp->pmhdl, fwudp->sock, POLLIN);
    if (status < 0) {
        closesocket(sock);
        free(fwudp->inbuf.buf);
        free(fwudp);
        return NULL;
    }

    fwudp->next = fwudp_list;
    fwudp_list = fwudp;

    return fwudp;
}