コード例 #1
0
ファイル: conn.c プロジェクト: alepharchives/spiped
/**
 * conn_accept(s, sas, decr, nofps, kfhash, nconn_max, timeo):
 * Start accepting connections on the socket ${s}.  Connect to the target
 * addresses ${sas}.  If ${decr} is 0, encrypt the outgoing connections; if
 * ${decr} is non-zero, decrypt the incoming connections.  Don't accept more
 * than ${nconn_max} connections.  If ${nofps} is non-zero, don't use perfect
 * forward secrecy.  Drop connections if the handshake or connecting to the
 * target takes more than ${timeo} seconds.
 */
int
conn_accept(int s, struct sock_addr * const * sas, int decr, int nofps,
    uint8_t kfhash[32], size_t nconn_max, double timeo)
{
	struct accept_state * A;

	/* Bake a cookie. */
	if ((A = malloc(sizeof(struct accept_state))) == NULL)
		goto err0;
	A->s = s;
	A->sas = sas;
	A->decr = decr;
	A->nofps = nofps;
	memcpy(A->kfhash, kfhash, 32);
	A->nconn = 0;
	A->nconn_max = nconn_max;
	A->timeo = timeo;
	A->accept_cookie = NULL;

	/* Accept a connection. */
	if (doaccept(A))
		goto err1;

	/* Success! */
	return (0);

err1:
	free(A);
err0:
	/* Failure! */
	return (-1);
}
コード例 #2
0
ファイル: conn.c プロジェクト: alepharchives/spiped
/* Drop a connection. */
static int
dropconn(struct conn_state * C)
{
	int rc = 0;

	/* Close the incoming connection. */
	C->A->nconn -= 1;
	close(C->s);

	/* Close the outgoing connection if it is open. */
	if (C->t != -1)
		close(C->t);

	/* Stop connecting if a connection is in progress. */
	if (C->connect_cookie != NULL)
		network_connect_cancel(C->connect_cookie);

	/* Stop handshaking if a handshake is in progress. */
	if (C->handshake_cookie != NULL)
		proto_handshake_cancel(C->handshake_cookie);

	/* Kill timeouts if they are pending. */
	if (C->connect_timeout_cookie != NULL)
		events_timer_cancel(C->connect_timeout_cookie);
	if (C->handshake_timeout_cookie != NULL)
		events_timer_cancel(C->handshake_timeout_cookie);

	/* Free protocol keys. */
	pcrypt_free(C->k_f);
	pcrypt_free(C->k_r);

	/* Shut down pipes. */
	if (C->pipe_f != NULL)
		proto_pipe_cancel(C->pipe_f);
	if (C->pipe_r != NULL)
		proto_pipe_cancel(C->pipe_r);

	/* Accept more connections if we need to. */
	if (doaccept(C->A))
		rc = -1;

	/* Free the connection cookie. */
	free(C);

	/* Return success/fail status. */
	return (rc);
}
コード例 #3
0
ファイル: main.cpp プロジェクト: JohnsonRanger/cerl
int main(int argc, char** argv)
{
	if (argc != 2)
	{
		printf("Usage: %s <ClientCounts>\n", argv[0]);
		return 1;
	}

	if (sscanf(argv[1], "%d", &g_nclimax) != 1)
	{
		printf("param error.\n");
		return 1;
	}

	int socket1 = cerl::listenSocket(8888);
	if(socket1 == -1)
	{
		perror("socket create failed: ");
		return 0;
	}

	//epoll
	int epfd = epoll_create(1000);
	if(epfd == -1)
	{
		perror("listen failed: ");
		close(socket1);
		return 0;
	}

	SockData listenSock = {0};
	listenSock.epfd = epfd;
	listenSock.socket = socket1;

	epoll_event	ev = {0};
	ev.events = EPOLLIN;
	ev.data.ptr = &listenSock;

	if(epoll_ctl(epfd, EPOLL_CTL_ADD, socket1, &ev) == -1)
	{
		perror("add listener to epoll failed:\n");
		close(epfd);
		close(socket1);
		return 0;
	}
	printf("listener %d added to epoll\n", socket1);

	epoll_event rcvev[128];

	bool isRun = true;

	while(isRun)
	{
		int nev = epoll_wait(epfd, rcvev, 128, -1);
		if(nev == -1)
		{
			perror("epoll wait failed:\n");
			close(epfd);
			close(socket1);
			return 0;
		}

		for(int i=0; i < nev; ++i)
		{
			SockData*	sd = (SockData*)rcvev[i].data.ptr;
			if(sd->socket != socket1)
			{
				dorw(rcvev[i], sd);
			}
			else
			{
				doaccept(rcvev[i], sd);
			}
		}
	}
	close(socket1);
	close(epfd);

	return 0;
}
コード例 #4
0
ファイル: select.cpp プロジェクト: hailong0715/CodeSegment
int main()
{
	int listenfd;
	struct sockaddr_in serAddr;
	fd_set rdSet, allset;
	int fdArray[FD_SETSIZE] = {0};
	int maxfd;
	int flag;
	FD_ZERO(&rdSet);

	serAddr.sin_family =  AF_INET;
	serAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serAddr.sin_port = htons(12345);

	for(int i =0; i< FD_SETSIZE; i++)
		fdArray[i] = -1;
	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if(listenfd < 0)
	{
		perror("create socket failed.\n");
		exit(-1);
	}
	if(flag = fcntl(listenfd,F_GETFL,0) < 0)
	{
		perror("FCNTL ERROR");
		return -1;
	}
	flag |= O_NONBLOCK;
	if(fcntl(listenfd, F_SETFL, flag) < 0 )
	{
		perror("fcntl set error");
		return -1;
	}
	printf("max fd size = %d\n",FD_SETSIZE);
     /*一个端口释放后会等待两分钟之后才能再被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用。*/
     int reuse = 1;
     if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
          exit(-1);
	if(bind(listenfd, (struct sockaddr*)&serAddr, sizeof(serAddr)) < 0)
	{
		perror("bind error");
		exit(-1);
	}

	if(listen(listenfd, 64) < 0)
	{
		perror("listen failed.\n");
		exit(-1);
	}
	FD_SET(listenfd, &rdSet);
	fdArray[0] = listenfd;
	maxfd = listenfd;
	while(1)
	{
		allset = rdSet;  //select每次检查前都必须重置描述符集
		int n = select(maxfd+1, &allset, NULL, NULL, NULL);
		if(n < 0)
		{
			perror("select failed.\n");
			exit(-1);
		}

		if(FD_ISSET(listenfd, &allset))
		{
			int connfd  = doaccept(listenfd);
			if(connfd < 0)
				exit(-1);
			if(flag = fcntl(connfd,F_GETFL,0) < 0)
			{
				perror("FCNTL ERROR");
				return -1;
			}
			flag |= O_NONBLOCK;
			//如果不将客户端套接字设置为非阻塞服务器将阻塞在某一个客户端套接字
			//的recv调用上,其他客户端的请求得不到响应
			if(fcntl(connfd, F_SETFL, flag) < 0 )  
			{
				perror("fcntl set error");
				return -1;
			}
			FD_SET(connfd, &rdSet);
			for(int i=0; i< FD_SETSIZE; i++)
			{
				if(fdArray[i] == -1)
				{
					fdArray[i] = connfd;
					break;
				}
			}
			//重置当前最大描述符字
			maxfd = (maxfd > connfd ? maxfd:connfd);

		}

		for(int i = 1; i< maxfd; i++)
		{
			if(FD_ISSET(fdArray[i], &allset))
				doRead(fdArray[i]);
		}
	
	}
	
	return 0;
}
コード例 #5
0
ファイル: conn.c プロジェクト: alepharchives/spiped
/* Handle an incoming connection. */
static int
callback_gotconn(void * cookie, int s)
{
	struct accept_state * A = cookie;
	struct conn_state * C;

	/* This accept is no longer in progress. */
	A->accept_cookie = NULL;

	/* We have gained a connection. */
	A->nconn += 1;

	/* Bake a cookie for this connection. */
	if ((C = malloc(sizeof(struct conn_state))) == NULL)
		goto err1;
	C->A = A;
	C->s = s;
	C->t = -1;
	C->connect_cookie = NULL;
	C->handshake_cookie = NULL;
	C->connect_timeout_cookie = C->handshake_timeout_cookie = NULL;
	C->k_f = C->k_r = NULL;
	C->pipe_f = C->pipe_r = NULL;
	C->stat_f = C->stat_r = 1;

	/* Start the connect timer. */
	if ((C->connect_timeout_cookie = events_timer_register_double(
	    callback_connect_timeout, C, C->A->timeo)) == NULL)
		goto err2;

	/* Connect to target. */
	if ((C->connect_cookie =
	    network_connect(A->sas, callback_connect_done, C)) == NULL)
		goto err3;

	/* If we're decrypting, start the handshake. */
	if (C->A->decr) {
		if (starthandshake(C, C->s, C->A->decr))
			goto err4;
	}

	/* Accept another connection if we can. */
	if (doaccept(A))
		goto err0;

	/* Success! */
	return (0);

err4:
	network_connect_cancel(C->connect_cookie);
err3:
	events_timer_cancel(C->connect_timeout_cookie);
err2:
	free(C);
err1:
	A->nconn -= 1;
	close(s);
err0:
	/* Failure! */
	return (-1);
}