void udp_add_readbuf(struct udp_con *con, u_char *dat, u_int datlen) { struct conbuffer *buf; hooks_dispatch(IP_PROTO_UDP, HD_INCOMING_STREAM, &con->conhdr, dat, datlen); if (con->cmd_pfd == -1) return; if (con->nincoming >= MAX_UDP_BUFFERS) return; buf = malloc(sizeof(struct conbuffer)); if (buf == NULL) return; buf->buf = malloc(datlen); if (buf->buf == NULL) { free(buf); return; } memcpy(buf->buf, dat, datlen); buf->len = datlen; TAILQ_INSERT_TAIL(&con->incoming, buf, next); con->nincoming++; cmd_trigger_write(&con->cmd, 1); }
void cmd_udp_write(int fd, short which, void *arg) { struct udp_con *con = arg; struct conbuffer *buf; ssize_t len; buf = TAILQ_FIRST(&con->incoming); if (buf == NULL) return; TRACE(fd, len = write(fd, buf->buf, buf->len)); if (len == -1) { if (errno == EINTR || errno == EAGAIN) goto again; cmd_free(&con->cmd); return; } else if (len == 0) { cmd_free(&con->cmd); return; } TAILQ_REMOVE(&con->incoming, buf, next); con->nincoming--; free(buf->buf); free(buf); again: cmd_trigger_write(&con->cmd, TAILQ_FIRST(&con->incoming) != NULL); }
void cmd_tcp_connect_cb(evutil_socket_t fd, short which, void *arg) { struct tcp_con *con = arg; int error = 0; socklen_t errsz = sizeof(error); /* Everything is ready */ cmd_ready_fd(&con->cmd, &cb_tcp, con); if (which == EV_TIMEOUT) goto out; /* Check if the connection completed */ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &errsz) == -1) { warn("%s: getsockopt for %d", __FUNCTION__, fd); goto out; } if (error) { warnx("%s: getsockopt: %s", __FUNCTION__, strerror(error)); goto out; } cmd_trigger_read(&con->cmd, con->psize - con->plen); cmd_trigger_write(&con->cmd, con->rlen); return; out: /* Connection failed, bring this down gracefully */ cmd_free(&con->cmd); tcp_sendfin(con); }
void cmd_tcp_write(evutil_socket_t fd, short which, void *arg) { struct tcp_con *con = arg; int len; TRACE(fd, len = write(fd, con->readbuf, con->rlen)); if (len == -1) { if (errno == EINTR || errno == EAGAIN) goto again; cmd_free(&con->cmd); return; } else if (len == 0) { cmd_free(&con->cmd); return; } memmove(con->readbuf, con->readbuf + len, con->rlen - len); con->rlen -= len; /* Shut down the connection if we received a FIN and sent all data */ if (con->rlen == 0 && con->cmd.fdgotfin) TRACE(con->cmd_pfd, shutdown(con->cmd_pfd, SHUT_WR)); again: cmd_trigger_write(&con->cmd, con->rlen); }
int tcp_add_readbuf(struct tcp_con *con, u_char *dat, u_int datlen) { int space; hooks_dispatch(IP_PROTO_TCP, HD_INCOMING_STREAM, &con->conhdr, dat, datlen); if (con->cmd_pfd == -1) return (datlen); space = con->rsize - con->rlen; if (space < datlen) { tcp_increase_buf(&con->readbuf, &con->rsize, TCP_MAX_SIZE); space = con->rsize - con->rlen; if (space < datlen) datlen = space; } memcpy(con->readbuf + con->rlen, dat, datlen); con->rlen += datlen; cmd_trigger_write(&con->cmd, con->rlen); return (datlen); }
void cmd_udp_connect_cb(int fd, short which, void *arg) { struct udp_con *con = arg; /* Everything is ready */ cmd_ready_fd(&con->cmd, &cb_udp, con); cmd_trigger_read(&con->cmd, 1); cmd_trigger_write(&con->cmd, TAILQ_FIRST(&con->incoming) != NULL); return; }