void CTcpSocket::on_inter_accept_accept(evutil_socket_t fd, std::string peerip, unsigned int peerport) { XH_GUARD([&]{Release(); }); m_status = status_connect; m_socket = fd; setnonblocking(m_socket); setnodelay(m_socket); //setlingerclose(m_socket); m_peerip = peerip; m_peerport = peerport; socketaddr localaddr; ev_socklen_t locallen = sizeof(localaddr); if (0 == getsockname(m_socket, (struct sockaddr*)&localaddr, &locallen)) { sockaddr2ipport(&localaddr, locallen, m_localip, m_localport); } m_io->Reset_Event(&m_ev_read, m_socket, EV_READ | EV_PERSIST, &CTcpSocket::on_recv_callback, this); m_io->Reset_Event(&m_ev_write, m_socket, EV_WRITE | EV_PERSIST, &CTcpSocket::on_send_callback, this); m_bassign |= 0x01; m_bassign |= 0x02; m_io->Add_TcpSocket(this); // 可以设置一个超时时间, struct timeval writeval; writeval.tv_sec = sf_connect_timeout; writeval.tv_usec = 0; m_io->Add_Event(&m_ev_write, &writeval); XH_LOG_INFO(logname_base, "[id:" << m_id << "] tcpsocket accept succeed, peerip:" << m_peerip << ", peerport : " << m_peerport); }
/* * To start a new USB/IP attachment, a userland program needs to setup a TCP * connection and then write its socket descriptor with remote device * information into this sysfs file. * * A remote device is virtually attached to the root-hub port of @rhport with * @speed. @busnum and @devnum are used to convert URBs between a client host * and a server host. * * write() returns 0 on success, else negative errno. */ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vhci_device *vdev; struct socket *socket; int sockfd = 0; __u32 rhport=0, busnum=0, devnum=0, speed=0; /* * @rhport: port number of vhci_hcd * @sockfd: socket descriptor of an established TCP connection * @busnum: usb bus number in a remote host * @devnum: usb device number in a remote host * @speed: usb device speed in a remote host */ sscanf(buf, "%u %u %u %u %u", &rhport, &sockfd, &busnum, &devnum, &speed); dbg_vhci_sysfs("rhport(%u) sockfd(%u) busnum(%u) devnum(%u) speed(%u)\n", rhport, sockfd, busnum, devnum, speed); /* check received parameters */ if (valid_args(rhport, busnum, devnum, speed) < 0) return -EINVAL; /* check sockfd */ socket = sockfd_to_socket(sockfd); if (!socket) return -EINVAL; #if 0 setnodelay(socket); #endif /* now need lock until setting vdev status as used */ /* begin a lock */ spin_lock(&the_controller->lock); vdev = port_to_vdev(rhport); spin_lock(&vdev->ud.lock); if (vdev->ud.status != VDEV_ST_NULL) { /* end of the lock */ spin_unlock(&vdev->ud.lock); spin_unlock(&the_controller->lock); uerr("port %d already used\n", rhport); return -EINVAL; } uinfo("rhport(%u) sockfd(%d) busnum(%u) devnum(%u) speed(%u)\n", rhport, sockfd, busnum, devnum, speed); vdev->busnum = busnum; vdev->devnum = devnum; vdev->speed = speed; vdev->ud.tcp_socket = socket; vdev->ud.status = VDEV_ST_NOTASSIGNED; spin_unlock(&vdev->ud.lock); spin_unlock(&the_controller->lock); /* end the lock */ /* * this function will sleep, so should be out of the lock. but, it's ok * because we already marked vdev as being used. really? */ usbip_start_threads(&vdev->ud); rh_port_connect(rhport, speed); return count; }
void CTcpSocket::real_connect(std::string ip, unsigned int port) { XH_GUARD([&]{Release(); }); if (!m_binit) return; m_peerip = ip; m_peerport = port; m_status = status_connect; socketaddr connectaddr; ev_socklen_t addrlen = sizeof(connectaddr); if (!ipport2sockaddr(m_peerip, m_peerport, &connectaddr, addrlen)) { XH_LOG_ERROR(logname_base, "[id:" << m_id << "] tcpsocket connect failed errip, ip:" << ip << ", port : " << port); on_inter_close(tcp_connectfail_iperr, true); return; } struct sockaddr* tempsockaddr = (struct sockaddr*)(&connectaddr); evutil_socket_t connecter; if ((connecter = ::socket(tempsockaddr->sa_family, SOCK_STREAM, 0)) == INVALID_SOCKET) { XH_LOG_ERROR(logname_base, "[id:" << m_id << "] tcpsocket connect failed::socket err, ip:" << ip << ", port : " << port); on_inter_close(tcp_connectfail_createerr, true); return; } setnonblocking(connecter); setnodelay(connecter); //setlingerclose(connecter); if (::connect(connecter, (struct sockaddr *) &connectaddr, addrlen) == SOCKET_ERROR) { if ( !isnoblockerr() ) { closetcpsocket(connecter); XH_LOG_ERROR(logname_base, "[id:" << m_id << "] tcpsocket connect failed::connect err, ip:" << ip << ", port : " << port); on_inter_close(tcp_connectfail_connecterr, true); return; } } m_socket = connecter; socketaddr localaddr; ev_socklen_t locallen = sizeof(localaddr); if (0 == getsockname(m_socket, (struct sockaddr*)&localaddr, &locallen)) { sockaddr2ipport(&localaddr, locallen, m_localip, m_localport); } m_io->Reset_Event(&m_ev_read, m_socket, EV_READ | EV_PERSIST, &CTcpSocket::on_recv_callback, this); m_io->Reset_Event(&m_ev_write, m_socket, EV_WRITE | EV_PERSIST, &CTcpSocket::on_send_callback, this); m_bassign |= 0x01; m_bassign |= 0x02; m_io->Add_TcpSocket(this); // 可以设置一个超时时间, struct timeval writeval; writeval.tv_sec = sf_connect_timeout; writeval.tv_usec = 0; m_io->Add_Event(&m_ev_write, &writeval); XH_LOG_INFO(logname_base, "[id:" << m_id << "] tcpsocket connect succeed, ip:" << ip << ", port : " << port); }
void CTcpSocket::real_listen(std::string ip, unsigned int port) { XH_GUARD([&]{Release(); }); if (!m_binit) return; m_localip = ip; m_localport = port; m_status = status_connect; socketaddr bindaddr; ev_socklen_t addrlen = sizeof(bindaddr); if (!ipport2sockaddr(m_localip, m_localport, &bindaddr, addrlen)) { XH_LOG_ERROR(logname_base, "[id:" << m_id << "] tcpsocket listen failed iperr, ip:" << ip << ", port : " << port); on_inter_close(tcp_listenfail_iperr, true); return; } struct sockaddr* tempsockaddr = (struct sockaddr*)(&bindaddr); evutil_socket_t listener; if ((listener = ::socket(tempsockaddr->sa_family, SOCK_STREAM, 0)) == INVALID_SOCKET) { XH_LOG_ERROR(logname_base, "[id:" << m_id << "] tcpsocket listen failed::socket err, ip:" << ip << ", port : " << port); on_inter_close(tcp_listenfail_createerr, true); return; } CScopeGuard guard_close([&]{closetcpsocket(listener); }); if (::bind(listener, (struct sockaddr *) &bindaddr, addrlen) == SOCKET_ERROR) { XH_LOG_ERROR(logname_base, "[id:" << m_id << "] tcpsocket listen failed::bind err, ip:" << ip << ", port : " << port); on_inter_close(tcp_listenfail_binderr, true); return; } if (::listen(listener, SOMAXCONN) == SOCKET_ERROR) { XH_LOG_ERROR(logname_base, "[id:" << m_id << "] tcpsocket listen failed::listen err, ip:" << ip << ", port : " << port); on_inter_close(tcp_listenfail_listenerr, true); return; } setnonblocking(listener); setnodelay(listener); setreuseport(listener); //setlingerclose(listener); // 默认接收长度 //setrecvbuffer(listener, recvsize); //setsendbuffer(listener, sendsize); guard_close.Dismiss(); m_status = status_common; m_socket = listener; m_io->Reset_Event(&m_ev_read, m_socket, EV_READ|EV_PERSIST, &(CTcpSocket::on_accept_callback), this); m_bassign |= 0x01; m_io->Add_TcpSocket(this); m_io->Add_Event(&m_ev_read, 0); m_lcb->On_Listen(GetSocketID(), tcp_ok); XH_LOG_INFO(logname_base, "[id:" << m_id << "] tcpsocket listen succeed, ip:" << ip << ", port : " << port); }