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(); }
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; }
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(); } }
/*----------------------------------------------------------------------------*/ 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; }