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; }
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; }