Exemple #1
0
void UdpSocket::CreateConnection()
{
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
	if (IsIpv6())
	{
		if (GetSocket() == INVALID_SOCKET)
		{
			SOCKET s = CreateSocket(AF_INET6, SOCK_DGRAM, "udp");
			if (s == INVALID_SOCKET)
			{
				return;
			}
			SetNonblocking(true, s);
			Attach(s);
		}
		return;
	}
#endif
#endif
	if (GetSocket() == INVALID_SOCKET)
	{
		SOCKET s = CreateSocket(AF_INET, SOCK_DGRAM, "udp");
		if (s == INVALID_SOCKET)
		{
			return;
		}
		SetNonblocking(true, s);
		Attach(s);
	}
}
Exemple #2
0
void addfd(int epollfd,int fd,bool enable_ET)
{
    epoll_event event;
    /*
    struct epoll_event
    {
        uint32_t events;	[> Epoll events <]
        epoll_data_t data;	[> User data variable <]
    } __EPOLL_PACKE
    typedef union epoll_data
    {
    void *ptr;
    int fd;
    uint32_t u32;
    uint64_t u64;
    } epoll_data_t;
    */
    event.data.fd = fd;
    event.events = EPOLLIN;
    if(enable_ET)
    {
        event.events |=EPOLLET;
    }

    epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);

    SetNonblocking(fd);
}
Exemple #3
0
int UdpSocket::Bind(SocketAddress& ad, int range)
{
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		SetNonblocking(true);
		int n = bind(GetSocket(), ad, ad);
		int tries = range;
		while (n == -1 && tries--)
		{
			ad.SetPort(ad.GetPort() + 1);
			n = bind(GetSocket(), ad, ad);
		}
		if (n == -1)
		{
			Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL);
			SetCloseAndDelete();
#ifdef ENABLE_EXCEPTIONS
			throw Exception("bind() failed for UdpSocket, port:range: " + Utility::l2string(ad.GetPort()) + ":" + Utility::l2string(range));
#endif
			return -1;
		}
		m_bind_ok = true;
		m_port = ad.GetPort();
		return 0;
	}
	return -1;
}
Exemple #4
0
int SelectHandle(const int listenfd)
{
	int connectfd = -1;
	fd_set rset;
	int nready = 0;
	int err = 0;
	struct sockaddr_in clientaddr;
	socklen_t socklen = sizeof(clientaddr);
	
	while(1)
	{
		FD_ZERO(&rset);
		FD_SET(listenfd,&rset);

		nready = select(listenfd+1,&rset,NULL,NULL,NULL);
		if (nready < 0) {
			if (errno == EINTR) {
				continue;
			}
			err = errno;
			printf("select(),error:%s\n",strerror(errno));
			break;
		}
	
		if (FD_ISSET(listenfd,&rset)) {
			connectfd = accept(listenfd,(struct sockaddr*)&clientaddr,&socklen);
			if (connectfd < 0) {
				err = errno;
				printf("accept(),error:%s\n",strerror(errno));
				continue;
			} else {
				printf("accept client from %s:%d \n",inet_ntoa(clientaddr.sin_addr),clientaddr.sin_port);
                err = SetNonblocking(connectfd);
				if (0 != err) {
					err = errno;
					printf("SetNonblocking(),error:%s\n",strerror(errno));
					break;
				}
			}
		}

		err = ConnectSocketHandle(connectfd);
		if (err != 0) {
		  printf("ConnectSocketHandle(),error:%s\n",strerror(errno));
		  break;
		}

        if (connectfd != -1) {
            close(connectfd);
        }
	}
}
Exemple #5
0
void UdpSocket::SendToBuf(SocketAddress& ad, const char *data, int len, int flags)
{
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		SetNonblocking(true);
		if ((m_last_size_written = sendto(GetSocket(), data, len, flags, ad, ad)) == -1)
		{
			Handler().LogError(this, "sendto", Errno, StrError(Errno), LOG_LEVEL_ERROR);
		}
	}
}
Exemple #6
0
bool UdpSocket::Open(SocketAddress& ad)
{
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		SetNonblocking(true);
		if (connect(GetSocket(), ad, ad) == -1)
		{
			Handler().LogError(this, "connect", Errno, StrError(Errno), LOG_LEVEL_FATAL);
			SetCloseAndDelete();
			return false;
		}
		SetConnected();
		return true;
	}
	return false;
}
Exemple #7
0
int SctpSocket::Open(SocketAddress& ad)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR);
		return -1;
	}
	if (GetSocket() == INVALID_SOCKET)
	{
		Attach(CreateSocket(ad.GetFamily(), m_type, "sctp"));
	}
	if (GetSocket() != INVALID_SOCKET)
	{
		if (!SetNonblocking(true))
		{
			return -1;
		}
		int n = connect(GetSocket(), ad, ad);
		if (n == -1)
		{
			// check error code that means a connect is in progress
#ifdef _WIN32
			if (Errno == WSAEWOULDBLOCK)
#else
			if (Errno == EINPROGRESS)
#endif
			{
				Handler().LogError(this, "connect: connection pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
				SetConnecting( true ); // this flag will control fd_set's
			}
			else
			{
				Handler().LogError(this, "SctpSocket", -1, "connect() failed", LOG_LEVEL_ERROR);
			}
		}
		return n;
	}
	return -1;
}
int NetClient::CreateSocket(bool usingtcp /* = false */)
{
    do {
        int typ = usingtcp ? SOCK_STREAM : SOCK_DGRAM;
        int fd = socket(AF_INET, typ, 0);
        if (fd < 0)
            break;

				if (usingtcp) {
					int val = 1;
					setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&val, sizeof(val));
					//setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&val, sizeof(val)); 
				} else {
					int buf_size = 65535;
					setsockopt ( fd, SOL_SOCKET, SO_RCVBUF, ( const char * ) &buf_size, sizeof ( buf_size ) );
					setsockopt ( fd, SOL_SOCKET, SO_SNDBUF, ( const char * ) &buf_size, sizeof ( buf_size ) );
				}

#ifndef WIN32
                //recv timeout
                struct timeval timeout={15,0};//15s
                setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
#endif

#ifdef IOS
                int set = 1;  
                setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));  
#endif

        if (!SetNonblocking(fd, true)) {
            close_socket(fd);
            break;
        }

        return fd;
    } while (0);

	return INVALID_SOCKET;
}
Exemple #9
0
bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks)
{
	if (!ad.IsValid())
	{
		Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL);
		SetCloseAndDelete();
		return false;
	}
	if (Handler().GetCount() >= Handler().MaxCount())
	{
		Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL);
		SetCloseAndDelete();
		return false;
	}
	SetConnecting(false);
#ifdef ENABLE_SOCKS4
	SetSocks4(false);
#endif
	// check for pooling
#ifdef ENABLE_POOL
	if (Handler().PoolEnabled())
	{
		ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad);
		if (pools)
		{
			CopyConnection( pools );
			delete pools;

			SetIsClient();
			SetCallOnConnect(); // ISocketHandler must call OnConnect
			Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO);
			return true;
		}
	}
#endif
	// if not, create new connection
	SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp");
	if (s == INVALID_SOCKET)
	{
		return false;
	}
	// socket must be nonblocking for async connect
	if (!SetNonblocking(true, s))
	{
		SetCloseAndDelete();
		closesocket(s);
		return false;
	}
#ifdef ENABLE_POOL
	SetIsClient(); // client because we connect
#endif
	SetClientRemoteAddress(ad);
	int n = 0;
	if (bind_ad.GetPort() != 0)
	{
		bind(s, bind_ad, bind_ad);
	}
#ifdef ENABLE_SOCKS4
	if (!skip_socks && GetSocks4Host() && GetSocks4Port())
	{
		Ipv4Address sa(GetSocks4Host(), GetSocks4Port());
		{
			std::string sockshost;
			Utility::l2ip(GetSocks4Host(), sockshost);
			Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" +
				Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO);
		}
		SetSocks4();
		n = connect(s, sa, sa);
		SetRemoteAddress(sa);
	}
	else
#endif
	{
		n = connect(s, ad, ad);
		SetRemoteAddress(ad);
	}
	if (n == -1)
	{
		// check error code that means a connect is in progress
#ifdef _WIN32
		if (Errno == WSAEWOULDBLOCK)
#else
		if (Errno == EINPROGRESS)
#endif
		{
			Attach(s);
			SetConnecting( true ); // this flag will control fd_set's
		}
		else
#ifdef ENABLE_SOCKS4
		if (Socks4() && Handler().Socks4TryDirect() ) // retry
		{
			closesocket(s);
			return Open(ad, true);
		}
		else
#endif
#ifdef ENABLE_RECONNECT
		if (Reconnect())
		{
			Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
			Attach(s);
			SetConnecting( true ); // this flag will control fd_set's
		}
		else
#endif
		{
			Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL);
			SetCloseAndDelete();
			closesocket(s);
			return false;
		}
	}
	else
	{
		Attach(s);
		SetCallOnConnect(); // ISocketHandler must call OnConnect
	}

	// 'true' means connected or connecting(not yet connected)
	// 'false' means something failed
	return true; //!Connecting();
}
Exemple #10
0
static void on_accept(int sock,short event,void *arg)
{
    Proxyer* pserver = (Proxyer*) arg;
    int clientsocket = -1;
    int remotesocket = -1;
    Context* newcontext = NULL;
    int err = 0;
    struct sockaddr_in client_addr,remote_addr;
    socklen_t len = sizeof(client_addr);

    do {
        clientsocket = accept(sock,(struct sockaddr *)&client_addr,&len);
        if ( -1 == clientsocket ) {
            std::cerr<<"accept client failed! err: "<<strerror(errno)<<std::endl;
            break;
        }
        std::cout<<"receive connection "<<GetPeerInfo(&client_addr)<<std::endl;
        
        err = SetNonblocking(clientsocket);
        if ( 0 != err ) {
            std::cerr<<"set nonblocking for client socket failed! err: "<<strerror(err)<<std::endl;
            break;
        }

        remotesocket = socket(AF_INET,SOCK_STREAM,0);
        if ( -1 == remotesocket ) {
            std::cerr<<"create remote socket failed!"<<std::endl;
            break;
        }

        memset(&remote_addr,0,sizeof(remote_addr));
        remote_addr.sin_family = AF_INET;
        remote_addr.sin_port = htons(pserver->remote_port);
        remote_addr.sin_addr.s_addr = inet_addr(pserver->remote_addr.c_str());

        err = connect(remotesocket,(struct sockaddr*)&remote_addr,sizeof(remote_addr));
        if ( 0 != err ) {
            if ( EINPROGRESS != err ) {
                err = errno;
                std::cerr<<"connect remote failed! err: "<<strerror(err)<<std::endl;
                break;
            }
            err = CheckConnect(remotesocket);
            if ( 0 != err ) {
                err = errno;
                std::cerr<<"connect remote failed! err: "<<strerror(err)<<std::endl;
                break;
            }
            std::cout<<"connect remote success!"<<std::endl;
        } else {
            std::cout<<"connect remote success!"<<std::endl;
        }

        /**
         * connect remote success,then we need to create a Context
         * */

        newcontext = new Context(pserver,clientsocket,remotesocket);
        if ( NULL == newcontext ) {
            std::cerr<<"Alloc Context failed!"<<std::endl;
            break;
        }

        err = newcontext->Init();
        if ( 0 != err ) {
            std::cerr<<"newcontext init failed!"<<std::endl;
            break;
        }

        /**
         * 将context添加到server的队列中
         * */
        pserver->m_context_list.push_back(newcontext);
    } while(0);

    do{
        if ( 0 != err ) {
            if ( -1 == clientsocket ) {
                 break;
             }
            close(clientsocket);

            if ( -1 == remotesocket ) {
                break;
            }
            close(remotesocket);

            if ( NULL == newcontext ) {
                break;
            }
            delete newcontext;
       }
    } while(0);

}
Exemple #11
0
int EventLoop::AddEvent(IOEvent *e) {
  e->el_ = this;
  SetNonblocking(e->fd_);
  return SetEvent(e, EPOLL_CTL_ADD);
}
Exemple #12
0
int main(int argc,char *argv[])
{
	int listenfd;
	int serverPort = 8888;
	struct sockaddr_in serveraddr;
	int nread = 0;
	int nwrite = 0;
	int err = 0;
	int ret = 0;
	socklen_t socklen = sizeof(serveraddr);
	
	do{
		listenfd = socket(AF_INET,SOCK_STREAM,0);
		if (listenfd < 0) {
			err = errno;
			printf("socket(),error:%s\n",strerror(errno));
			break;
		}
		
		int opt = 1;
		if (setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)) < 0) {
			err = errno;
			printf("setsockopt(),error:%s\n",strerror(errno));
			break;
		}
	
		bzero(&serveraddr,sizeof(serveraddr));
		serveraddr.sin_family = AF_INET;
		serveraddr.sin_addr.s_addr = INADDR_ANY;
		serveraddr.sin_port = htons(8888);
		
		ret = bind(listenfd,(struct sockaddr*)&serveraddr,socklen);
		if (ret < 0) {
			err = errno;
			printf("bind(),error:%s\n",strerror(errno));
			break;
		}
				
		ret = listen(listenfd,1024);
		if (ret < 0) {
			err = errno;
			printf("listen(),error:%s\n",strerror(errno));
			break;
		}

		err = SetNonblocking(listenfd);
		if (0 != err) {
			err = errno;
			printf("setnonblockint(),error:%s\n",strerror(errno));
			break;		
		}

		printf("server startup,listen on port 8888!\n");
		err = SelectHandle(listenfd);
		if (0 != err) {
			printf("SelectHandle(),error:%s\n",strerror(errno));	
			break;
		}
	} while(0);	
	
	if (-1 != listenfd) {
		close(listenfd);
    }

	return err;
}