X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fvconn-tcp.c;h=aac716623de0ed09845c1cbf12d7c45014fbe3e8;hb=4e256b6bf053a0c4ef9a599f83e647daca3b21a6;hp=50367806f3d420d5b5cd68825f2e26273d1a3163;hpb=193456d581423f894e57e8463ff5049c0d802f0a;p=openvswitch diff --git a/lib/vconn-tcp.c b/lib/vconn-tcp.c index 50367806..aac71662 100644 --- a/lib/vconn-tcp.c +++ b/lib/vconn-tcp.c @@ -36,15 +36,21 @@ /* Active TCP. */ -void tcp_connect_success_cb(struct vconn *vconn, int fd); - static int new_tcp_vconn(const char *name, int fd, int connect_status, - const struct sockaddr_in *sin, struct vconn **vconnp) + const struct sockaddr_in *remote, struct vconn **vconnp) { + struct sockaddr_in local; + socklen_t local_len = sizeof local; int on = 1; int retval; + /* Get the local IP and port information */ + retval = getsockname(fd, (struct sockaddr *)&local, &local_len); + if (retval) { + memset(&local, 0, sizeof local); + } + retval = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); if (retval) { VLOG_ERR("%s: setsockopt(TCP_NODELAY): %s", name, strerror(errno)); @@ -52,76 +58,30 @@ new_tcp_vconn(const char *name, int fd, int connect_status, return errno; } - return new_stream_vconn(name, fd, connect_status, - sin->sin_addr.s_addr, sin->sin_port, - true, tcp_connect_success_cb, vconnp); + retval = new_stream_vconn(name, fd, connect_status, NULL, vconnp); + if (!retval) { + struct vconn *vconn = *vconnp; + vconn_set_remote_ip(vconn, remote->sin_addr.s_addr); + vconn_set_remote_port(vconn, remote->sin_port); + vconn_set_local_ip(vconn, local.sin_addr.s_addr); + vconn_set_local_port(vconn, local.sin_port); + } + return retval; } static int tcp_open(const char *name, char *suffix, struct vconn **vconnp) { - char *save_ptr; - const char *host_name; - const char *port_string; struct sockaddr_in sin; - int retval; - int fd; + int fd, error; - host_name = strtok_r(suffix, ":", &save_ptr); - port_string = strtok_r(NULL, ":", &save_ptr); - if (!host_name) { - ovs_error(0, "%s: bad peer name format", name); - return EAFNOSUPPORT; - } - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - if (lookup_ip(host_name, &sin.sin_addr)) { - return ENOENT; - } - sin.sin_port = htons(port_string ? atoi(port_string) : OFP_TCP_PORT); - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - VLOG_ERR("%s: socket: %s", name, strerror(errno)); - return errno; - } - - retval = set_nonblocking(fd); - if (retval) { - close(fd); - return retval; - } - - retval = connect(fd, (struct sockaddr *) &sin, sizeof sin); - if (retval < 0) { - if (errno == EINPROGRESS) { - return new_tcp_vconn(name, fd, EAGAIN, &sin, vconnp); - } else { - int error = errno; - VLOG_ERR("%s: connect: %s", name, strerror(error)); - close(fd); - return error; - } + error = inet_open_active(SOCK_STREAM, suffix, OFP_TCP_PORT, &sin, &fd); + if (fd >= 0) { + return new_tcp_vconn(name, fd, error, &sin, vconnp); } else { - return new_tcp_vconn(name, fd, 0, &sin, vconnp); - } -} - -void -tcp_connect_success_cb(struct vconn *vconn, int fd) -{ - int retval; - struct sockaddr_in local_addr; - socklen_t addrlen = sizeof(local_addr); - - /* Get the local IP and port information */ - retval = getsockname(fd, (struct sockaddr *)&local_addr, &addrlen); - if (retval) { - memset(&local_addr, 0, sizeof local_addr); + VLOG_ERR("%s: connect: %s", name, strerror(error)); + return error; } - vconn_set_local_ip(vconn, local_addr.sin_addr.s_addr); - vconn_set_local_port(vconn, local_addr.sin_port); } struct vconn_class tcp_vconn_class = { @@ -140,37 +100,16 @@ static int ptcp_accept(int fd, const struct sockaddr *sa, size_t sa_len, struct vconn **vconnp); static int -ptcp_open(const char *name, char *suffix, struct pvconn **pvconnp) +ptcp_open(const char *name UNUSED, char *suffix, struct pvconn **pvconnp) { - struct sockaddr_in sin; - int retval; int fd; - unsigned int yes = 1; - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = inet_open_passive(SOCK_STREAM, suffix, OFP_TCP_PORT); if (fd < 0) { - VLOG_ERR("%s: socket: %s", name, strerror(errno)); - return errno; - } - - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) < 0) { - VLOG_ERR("%s: setsockopt(SO_REUSEADDR): %s", name, strerror(errno)); - return errno; - } - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_ANY); - sin.sin_port = htons(atoi(suffix) ? atoi(suffix) : OFP_TCP_PORT); - retval = bind(fd, (struct sockaddr *) &sin, sizeof sin); - if (retval < 0) { - int error = errno; - VLOG_ERR("%s: bind: %s", name, strerror(error)); - close(fd); - return error; + return -fd; + } else { + return new_pstream_pvconn("ptcp", fd, ptcp_accept, NULL, pvconnp); } - - return new_pstream_pvconn("ptcp", fd, ptcp_accept, pvconnp); } static int