Пример #1
0
bool HttpServer::Init(const char* servicePort)
{
  addrinfo addrHints = {0};
  addrHints.ai_family = PF_INET; // Only IPv4
  addrHints.ai_flags = AI_PASSIVE;
  addrHints.ai_socktype = SOCK_STREAM;
  
  int result = 0;
  
  addrinfo* addrInfoHead;
  if ((result = ::getaddrinfo(nullptr, servicePort, &addrHints, &addrInfoHead)) != 0) {
    Tracer::LogErrNo(::gai_strerror(result));
    return false;
  }
  
  addrinfo* currAddrInfo = addrInfoHead;
  while (currAddrInfo != nullptr) {
    int currAddrFd = CreateListeningSocket(currAddrInfo);
    if (currAddrFd != -1) {
      _listeningFds.push_back(currAddrFd);
    }
    else {
      Tracer::Log("Failed to create a listening socket.\n");
    }
    
    currAddrInfo = currAddrInfo->ai_next;
  }
  
  ::freeaddrinfo(addrInfoHead); 
  
  return !_listeningFds.empty();
}
Пример #2
0
static void
UpdateListener( ARRAY8Ptr addr, void **closure )
{
	struct socklist *s;

	*closure = NULL;

	if (addr == NULL) {
		ARRAY8 tmpaddr;
		struct in_addr in;
#if defined(IPv6) && defined(AF_INET6)
		struct in6_addr in6 = in6addr_any;
		tmpaddr.length = sizeof(in6);
		tmpaddr.data = (CARD8Ptr) &in6;
		UpdateListener( &tmpaddr, closure );
		if (*closure)
			return;
#endif
		in.s_addr = htonl( INADDR_ANY );
		tmpaddr.length = sizeof(in);
		tmpaddr.data = (CARD8Ptr) ∈
		UpdateListener( &tmpaddr, closure );
		return;
	}

	if (c_request_port == request_port &&
	    (s = FindInList( listensocks, addr )))
	{
		*closure = (void *)s;
		s->ref = 1;
		return;
	}

	if (!(s = CreateSocklistEntry( addr )))
		return;

	if ((s->fd = CreateListeningSocket( s->addr, s->salen )) < 0) {
		free( s->addr );
		free( s );
		return;
	}
	s->ref = 1;
	s->next = listensocks;
	listensocks = s;
	*closure = (void *)s;
}
Пример #3
0
void CSocketServer::StartAcceptingConnections()
{
	if ( INVALID_SOCKET == m_listeningSocket )
	{
		/*
		 * Call to unqualified virtual function
		 */
		OnStartAcceptingConnections();
		
		/*
		 * call to unqualified virtual function
		 */
		m_listeningSocket = CreateListeningSocket( m_address, m_port );
		
		m_acceptConnectionsEvent.Set();
	}
}
Пример #4
0
/*----------------------------------------------------------------------------*/
void *
RunServerThread(void *arg)
{
	int core = *(int *)arg;
	struct thread_context *ctx;
	mctx_t mctx;
	int listener;
	int ep;
	struct mtcp_epoll_event *events;
	int nevents;
	int i, ret;
	int do_accept;
	
	/* initialization */
	ctx = InitializeServerThread(core);
	if (!ctx) {
		TRACE_ERROR("Failed to initialize server thread.\n");
		return NULL;
	}
	mctx = ctx->mctx;
	ep = ctx->ep;

	events = (struct mtcp_epoll_event *)
			calloc(MAX_EVENTS, sizeof(struct mtcp_epoll_event));
	if (!events) {
		TRACE_ERROR("Failed to create event struct!\n");
		exit(-1);
	}

	listener = CreateListeningSocket(ctx);
	if (listener < 0) {
		TRACE_ERROR("Failed to create listening socket.\n");
		exit(-1);
	}

	while (!done[core]) {
		nevents = mtcp_epoll_wait(mctx, ep, events, MAX_EVENTS, -1);
		if (nevents < 0) {
			if (errno != EINTR)
				perror("mtcp_epoll_wait");
			break;
		}

		do_accept = FALSE;
		for (i = 0; i < nevents; i++) {

			if (events[i].data.sockid == listener) {
				/* if the event is for the listener, accept connection */
				do_accept = TRUE;

			} else if (events[i].events & MTCP_EPOLLERR) {
				int err;
				socklen_t len = sizeof(err);

				/* error on the connection */
				TRACE_APP("[CPU %d] Error on socket %d\n", 
						core, events[i].data.sockid);
				if (mtcp_getsockopt(mctx, events[i].data.sockid, 
						SOL_SOCKET, SO_ERROR, (void *)&err, &len) == 0) {
					if (err != ETIMEDOUT) {
						fprintf(stderr, "Error on socket %d: %s\n", 
								events[i].data.sockid, strerror(err));
					}
				} else {
					perror("mtcp_getsockopt");
				}
				CloseConnection(ctx, events[i].data.sockid, 
						&ctx->svars[events[i].data.sockid]);

			} else if (events[i].events & MTCP_EPOLLIN) {
				ret = HandleReadEvent(ctx, events[i].data.sockid, 
						&ctx->svars[events[i].data.sockid]);

				if (ret == 0) {
					/* connection closed by remote host */
					CloseConnection(ctx, events[i].data.sockid, 
							&ctx->svars[events[i].data.sockid]);
				} else if (ret < 0) {
					/* if not EAGAIN, it's an error */
					if (errno != EAGAIN) {
						CloseConnection(ctx, events[i].data.sockid, 
								&ctx->svars[events[i].data.sockid]);
					}
				}

			} else if (events[i].events & MTCP_EPOLLOUT) {
				struct server_vars *sv = &ctx->svars[events[i].data.sockid];
				if (sv->rspheader_sent) {
					SendUntilAvailable(ctx, events[i].data.sockid, sv);
				} else {
					TRACE_APP("Socket %d: Response header not sent yet.\n", 
							events[i].data.sockid);
				}

			} else {
				assert(0);
			}
		}

		/* if do_accept flag is set, accept connections */
		if (do_accept) {
			while (1) {
				ret = AcceptConnection(ctx, listener);
				if (ret < 0)
					break;
			}
		}

	}

	/* destroy mtcp context: this will kill the mtcp thread */
	mtcp_destroy_context(mctx);
	pthread_exit(NULL);

	return NULL;
}