Exemple #1
0
	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);
	}
Exemple #2
0
/*
 * 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;
}
Exemple #3
0
	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);
	}
Exemple #4
0
	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);
	}