int main(int argc, char **argv) { int sockfd, new_fd,numbytes; // listen on sock_fd, new connection on new_fd char buf[MAXDATASIZE]; struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; struct sigaction sa; int yes=1; char s[INET6_ADDRSTRLEN]; int rv,tempType=0; pid_t tempPid; PACKET tempPacket; if (argc==2 && (strcmp("-d",argv[1])==0)) { printf("== Daemon mode selected.==\n"); daemonFlag=1; } if (daemonFlag) { // Become a daemon: switch (fork ()) { case -1: // can't fork perror ("fork()"); exit (0); case 0: // child, process becomes a daemon: close (STDIN_FILENO); close (STDOUT_FILENO); close (STDERR_FILENO); if (setsid () == -1) // request a new session (job control) { exit (0); } break; default: // parent returns to calling process: return 0; } // Establish signal handler to clean up before termination: if (signal (SIGTERM, termination_handler) == SIG_IGN) signal (SIGTERM, SIG_IGN); signal (SIGINT, SIG_IGN); signal (SIGHUP, SIG_IGN); } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "server: failed to bind\n"); return 2; } freeaddrinfo(servinfo); // all done with this structure if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } printf("server(%d): waiting for connections...\n",getpid()); while(keep_going) { // main accept() loop sin_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { perror("accept"); continue; } inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); printf("server(%d): got connection from %s\n", getpid(),s); if (!fork()) { // this is the child process close(sockfd); // child doesn't need this descriptor openlog("DaemonServer",LOG_PID,LOG_SYSLOG); while (tempType!=2) {//child stops when client deregisters //recv packet if (recv(new_fd, (void*)&tempPacket, sizeof(tempPacket), 0) == -1) { perror("recv"); break; } tempType=tempPacket.packet_head.type; tempPid=tempPacket.packet_head.sender_pid; if (tempType<=3) { printf("server(%d): received msg type:'%d' from %s-client(%d) \n",getpid(), tempType,tempPacket.packet_head.mid,tempPid); syslog(LOG_NOTICE, "server(%d): received msg type:'%d' from %s-client(%d) \n",getpid(), tempType,tempPacket.packet_head.mid,tempPid); if (tempType==MSG_HEAD_NORMAL) { printf("server(%d): received following msg string from %s-client(%d): %s \n",getpid(),tempPacket.packet_head.mid,tempPid,tempPacket.packet_body.charbody); syslog(LOG_NOTICE, "server(%d): received following msg string from %s-client(%d): %s \n",getpid(),tempPacket.packet_head.mid,tempPid,tempPacket.packet_body.charbody); } //generate ACKs printf("server(%d): sent ACK type:'%d' to %s-client(%d)\n",getpid(), tempType+3,tempPacket.packet_head.mid,tempPid); syslog(LOG_NOTICE, "server(%d): received following msg string from %s-client(%d): %s \n",getpid(),tempPacket.packet_head.mid,tempPid,tempPacket.packet_body.charbody); generatePacket(&tempPacket, tempType+3, getpid(), "Server"); //send acks if (send(new_fd, (void*)&tempPacket, sizeof(tempPacket), 0) == -1) { perror("send"); break; } } } closelog(); close(new_fd); exit(0); } close(new_fd); // parent doesn't need this } return 0; }
/* Receive data from host and call *callback () * @param waitress handle * @return WaitressReturn_t */ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) { struct addrinfo hints, *res; int sockfd; char recvBuf[WAITRESS_RECV_BUFFER]; char writeBuf[2*1024]; ssize_t recvSize = 0; WaitressReturn_t wRet = WAITRESS_RET_OK; struct pollfd sockpoll; int pollres; /* header parser vars */ char *nextLine = NULL, *thisLine = NULL; enum {HDRM_HEAD, HDRM_LINES, HDRM_FINISHED} hdrParseMode = HDRM_HEAD; char statusCode[3], val[256]; unsigned int bufFilled = 0; /* initialize */ waith->contentLength = 0; waith->contentReceived = 0; memset (&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* Use proxy? */ if (WaitressProxyEnabled (waith)) { if (getaddrinfo (waith->proxyHost, waith->proxyPort, &hints, &res) != 0) { return WAITRESS_RET_GETADDR_ERR; } } else { if (getaddrinfo (waith->host, waith->port, &hints, &res) != 0) { return WAITRESS_RET_GETADDR_ERR; } } if ((sockfd = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { freeaddrinfo (res); return WAITRESS_RET_SOCK_ERR; } sockpoll.fd = sockfd; fcntl (sockfd, F_SETFL, O_NONBLOCK); /* increase socket receive buffer */ const int sockopt = 256*1024; setsockopt (sockfd, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof (sockopt)); /* non-blocking connect will return immediately */ connect (sockfd, res->ai_addr, res->ai_addrlen); sockpoll.events = POLLOUT; pollres = poll (&sockpoll, 1, waith->socktimeout); freeaddrinfo (res); if (pollres == 0) { return WAITRESS_RET_TIMEOUT; } else if (pollres == -1) { return WAITRESS_RET_ERR; } /* check connect () return value */ socklen_t pollresSize = sizeof (pollres); getsockopt (sockfd, SOL_SOCKET, SO_ERROR, &pollres, &pollresSize); if (pollres != 0) { return WAITRESS_RET_CONNECT_REFUSED; } /* send request */ if (WaitressProxyEnabled (waith)) { snprintf (writeBuf, sizeof (writeBuf), "%s http://%s:%s%s HTTP/1.0\r\n", (waith->method == WAITRESS_METHOD_GET ? "GET" : "POST"), waith->host, waith->port, waith->path); } else { snprintf (writeBuf, sizeof (writeBuf), "%s %s HTTP/1.0\r\n", (waith->method == WAITRESS_METHOD_GET ? "GET" : "POST"), waith->path); } WRITE_RET (writeBuf, strlen (writeBuf)); snprintf (writeBuf, sizeof (writeBuf), "Host: %s\r\nUser-Agent: " PACKAGE "\r\n", waith->host); WRITE_RET (writeBuf, strlen (writeBuf)); if (waith->method == WAITRESS_METHOD_POST && waith->postData != NULL) { snprintf (writeBuf, sizeof (writeBuf), "Content-Length: %zu\r\n", strlen (waith->postData)); WRITE_RET (writeBuf, strlen (writeBuf)); } if (waith->extraHeaders != NULL) { WRITE_RET (waith->extraHeaders, strlen (waith->extraHeaders)); } WRITE_RET ("\r\n", 2); if (waith->method == WAITRESS_METHOD_POST && waith->postData != NULL) { WRITE_RET (waith->postData, strlen (waith->postData)); } /* receive answer */ nextLine = recvBuf; while (hdrParseMode != HDRM_FINISHED) { READ_RET (recvBuf+bufFilled, sizeof (recvBuf)-1 - bufFilled, &recvSize); if (recvSize == 0) { /* connection closed too early */ CLOSE_RET (WAITRESS_RET_CONNECTION_CLOSED); } bufFilled += recvSize; memset (recvBuf+bufFilled, 0, sizeof (recvBuf) - bufFilled); thisLine = recvBuf; /* split */ while ((nextLine = strchr (thisLine, '\n')) != NULL && hdrParseMode != HDRM_FINISHED) { /* make lines parseable by string routines */ *nextLine = '\0'; if (*(nextLine-1) == '\r') { *(nextLine-1) = '\0'; } /* skip \0 */ ++nextLine; switch (hdrParseMode) { /* Status code */ case HDRM_HEAD: if (sscanf (thisLine, "HTTP/1.%*1[0-9] %3[0-9] ", statusCode) == 1) { if (memcmp (statusCode, "200", 3) == 0 || memcmp (statusCode, "206", 3) == 0) { /* everything's fine... */ } else if (memcmp (statusCode, "403", 3) == 0) { CLOSE_RET (WAITRESS_RET_FORBIDDEN); } else if (memcmp (statusCode, "404", 3) == 0) { CLOSE_RET (WAITRESS_RET_NOTFOUND); } else { CLOSE_RET (WAITRESS_RET_STATUS_UNKNOWN); } hdrParseMode = HDRM_LINES; } /* endif */ break; /* Everything else, except status code */ case HDRM_LINES: /* empty line => content starts here */ if (*thisLine == '\0') { hdrParseMode = HDRM_FINISHED; } else { memset (val, 0, sizeof (val)); if (sscanf (thisLine, "Content-Length: %255c", val) == 1) { waith->contentLength = atol (val); } } break; default: break; } /* end switch */ thisLine = nextLine; } /* end while strchr */ memmove (recvBuf, thisLine, thisLine-recvBuf); bufFilled -= (thisLine-recvBuf); } /* end while hdrParseMode */ /* push remaining bytes */ if (bufFilled > 0) { waith->contentReceived += bufFilled; if (waith->callback (thisLine, bufFilled, waith->data) == WAITRESS_CB_RET_ERR) { CLOSE_RET (WAITRESS_RET_CB_ABORT); } } /* receive content */ do { READ_RET (recvBuf, sizeof (recvBuf), &recvSize); if (recvSize > 0) { waith->contentReceived += recvSize; if (waith->callback (recvBuf, recvSize, waith->data) == WAITRESS_CB_RET_ERR) { wRet = WAITRESS_RET_CB_ABORT; break; } } } while (recvSize > 0); close (sockfd); if (wRet == WAITRESS_RET_OK && waith->contentReceived < waith->contentLength) { return WAITRESS_RET_PARTIAL_FILE; } return wRet; }
int NET_Socket ( char *net_interface, int port, netsrc_t type, int family ) { char Buf[BUFSIZ], *Host, *Service; int newsocket, Error; struct sockaddr_storage ss; struct addrinfo hints, *res, *ai; qboolean _true = true; int i = 1; struct ipv6_mreq mreq; cvar_t *mcast; memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; if (!net_interface || !net_interface[0] || !Q_stricmp(net_interface, "localhost")) { Host = (family == AF_INET6) ? "::" : "0.0.0.0"; } else { Host = net_interface; } if (port == PORT_ANY) { Service = NULL; } else { sprintf(Buf, "%5d", port); Service = Buf; } if ((Error = getaddrinfo(Host, Service, &hints, &res))) { return 0; } for (ai = res; ai != NULL; ai = ai->ai_next) { if ((newsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) { Com_Printf("NET_Socket: socket: %s\n", strerror(errno)); continue; } /* make it non-blocking */ if (ioctl(newsocket, FIONBIO, (char *)&_true) == -1) { Com_Printf("NET_Socket: ioctl FIONBIO: %s\n", strerror(errno)); continue; } if (family == AF_INET) { /* make it broadcast capable */ if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1) { Com_Printf("ERROR: NET_Socket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString()); return 0; } } /* make it reusable */ if (setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)) == -1) { Com_Printf("ERROR: NET_Socket: setsockopt SO_REUSEADDR:%s\n", NET_ErrorString()); return 0; } if (bind(newsocket, ai->ai_addr, ai->ai_addrlen) < 0) { Com_Printf("NET_Socket: bind: %s\n", strerror(errno)); } else { memcpy(&ss, ai->ai_addr, ai->ai_addrlen); break; } } if (res != NULL) { freeaddrinfo(res); } if (ai == NULL) { return 0; } switch (ss.ss_family) { case AF_INET: break; case AF_INET6: /* Multicast outgoing interface is specified for client and server (+set multicast <ifname>) */ mcast = Cvar_Get("multicast", "NULL", CVAR_NOSET); multicast_interface = (strcmp(mcast->string, "NULL") ? mcast->string : NULL); if (multicast_interface != NULL) { /* multicast_interface is a global variable. Also used in NET_SendPacket() */ if ((mreq.ipv6mr_interface = if_nametoindex(multicast_interface)) == 0) { Com_Printf("NET_Socket: invalid interface: %s\n", multicast_interface); } if (setsockopt(newsocket, IPPROTO_IPV6, IPV6_MULTICAST_IF, &mreq.ipv6mr_interface, sizeof(mreq.ipv6mr_interface)) < 0) { Com_Printf("NET_Socket: IPV6_MULTICAST_IF: %s\n", strerror(errno)); } /* Join multicast group ONLY if server */ if (type == NS_SERVER) { if (inet_pton(AF_INET6, QUAKE2MCAST, &mreq.ipv6mr_multiaddr.s6_addr) != 1) { Com_Printf("NET_Socket: inet_pton: %s\n", strerror(errno)); } if (setsockopt(newsocket, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) < 0) { Com_Printf("NET_Socket: IPV6_JOIN_GROUP: %s\n", strerror(errno)); } } } break; } return newsocket; }
krb5_error_code KRB5_LIB_FUNCTION krb5_parse_address(krb5_context context, const char *string, krb5_addresses *addresses) { int i, n; struct addrinfo *ai, *a; int error; int save_errno; addresses->len = 0; addresses->val = NULL; for(i = 0; i < num_addrs; i++) { if(at[i].parse_addr) { krb5_address addr; if((*at[i].parse_addr)(context, string, &addr) == 0) { ALLOC_SEQ(addresses, 1); if (addresses->val == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } addresses->val[0] = addr; return 0; } } } error = getaddrinfo (string, NULL, NULL, &ai); if (error) { krb5_error_code ret2; save_errno = errno; ret2 = krb5_eai_to_heim_errno(error, save_errno); krb5_set_error_message (context, ret2, "%s: %s", string, gai_strerror(error)); return ret2; } n = 0; for (a = ai; a != NULL; a = a->ai_next) ++n; ALLOC_SEQ(addresses, n); if (addresses->val == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); freeaddrinfo(ai); return ENOMEM; } addresses->len = 0; for (a = ai, i = 0; a != NULL; a = a->ai_next) { if (krb5_sockaddr2address (context, ai->ai_addr, &addresses->val[i])) continue; if(krb5_address_search(context, &addresses->val[i], addresses)) { krb5_free_address(context, &addresses->val[i]); continue; } i++; addresses->len = i; } freeaddrinfo (ai); return 0; }
void SocketTransport::listenForClientConnection() { // If there was a previous connection in the base class, shut it down. // This will close the old transport and wait for both the send and receive // worker threads to terminate before proceeding. if (getTransportFd() >= 0) { shutdown(); } VSDebugLogger::Log( VSDebugLogger::LogLevelInfo, "SocketTransport worker thread listening for connections..." ); int abortFd; { Lock lock(m_lock); abortFd = m_abortPipeFd[0]; assertx(abortFd >= 0); } struct addrinfo hint; struct addrinfo* ai = nullptr; std::vector<int> socketFds; memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_UNSPEC; hint.ai_socktype = SOCK_STREAM; hint.ai_flags = AI_PASSIVE; SCOPE_EXIT { if (ai != nullptr) { freeaddrinfo(ai); } for (auto it = socketFds.begin(); it != socketFds.end(); it++) { close(*it); } close(abortFd); m_abortPipeFd[0] = -1; VSDebugLogger::Log( VSDebugLogger::LogLevelInfo, "SocketTransport connection polling thread exiting." ); }; // Share existing DebuggerDisableIPv6 configuration with hphpd. if (RuntimeOption::DebuggerDisableIPv6) { hint.ai_family = AF_INET; } const auto name = RuntimeOption::DebuggerServerIP.empty() ? "localhost" : RuntimeOption::DebuggerServerIP.c_str(); if (getaddrinfo(name, std::to_string(m_listenPort).c_str(), &hint, &ai)) { VSDebugLogger::Log( VSDebugLogger::LogLevelError, "Failed to call getaddrinfo: %d.", errno ); return; } // Attempt to listen on the specified port on each of this host's available // addresses. struct addrinfo* address; bool anyInterfaceBound = false; for (address = ai; address != nullptr; address = address->ai_next) { if (bindAndListen(address, socketFds)) { anyInterfaceBound = true; } } if (!anyInterfaceBound) { VSDebugLogger::Log( VSDebugLogger::LogLevelWarning, "Debugger failed to bind to any interface!" ); return; } else { VSDebugLogger::Log( VSDebugLogger::LogLevelInfo, "Debugger bound to at least one interface." ); } waitForConnection(socketFds, abortFd); }
/* Creates a socket and listens on port 'port'. * Returns 1 on failure * Returns 0 on success. */ int mqtt3_socket_listen(struct _mqtt3_listener *listener) { int sock = -1; struct addrinfo hints; struct addrinfo *ainfo, *rp; char service[10]; int opt = 1; #ifndef WIN32 int ss_opt = 1; #else char ss_opt = 1; #endif #ifdef WITH_TLS int rc; X509_STORE *store; X509_LOOKUP *lookup; #endif char err[256]; if(!listener) return MOSQ_ERR_INVAL; snprintf(service, 10, "%d", listener->port); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; if(getaddrinfo(listener->host, service, &hints, &ainfo)) return INVALID_SOCKET; listener->sock_count = 0; listener->socks = NULL; for(rp = ainfo; rp; rp = rp->ai_next){ if(rp->ai_family == AF_INET){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Opening ipv4 listen socket on port %d.", ntohs(((struct sockaddr_in *)rp->ai_addr)->sin_port)); }else if(rp->ai_family == AF_INET6){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Opening ipv6 listen socket on port %d.", ntohs(((struct sockaddr_in6 *)rp->ai_addr)->sin6_port)); }else{ continue; } sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if(sock == -1){ strerror_r(errno, err, 256); _mosquitto_log_printf(NULL, MOSQ_LOG_WARNING, "Warning: %s", err); continue; } listener->sock_count++; listener->socks = _mosquitto_realloc(listener->socks, sizeof(int)*listener->sock_count); if(!listener->socks){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } listener->socks[listener->sock_count-1] = sock; #ifndef WIN32 ss_opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ss_opt, sizeof(ss_opt)); #endif ss_opt = 1; setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ss_opt, sizeof(ss_opt)); #ifndef WIN32 /* Set non-blocking */ opt = fcntl(sock, F_GETFL, 0); if(opt == -1 || fcntl(sock, F_SETFL, opt | O_NONBLOCK) == -1){ /* If either fcntl fails, don't want to allow this client to connect. */ COMPAT_CLOSE(sock); return 1; } #else if(ioctlsocket(sock, FIONBIO, &opt)){ COMPAT_CLOSE(sock); return 1; } #endif if(bind(sock, rp->ai_addr, rp->ai_addrlen) == -1){ strerror_r(errno, err, 256); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s", err); COMPAT_CLOSE(sock); return 1; } if(listen(sock, 100) == -1){ strerror_r(errno, err, 256); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s", err); COMPAT_CLOSE(sock); return 1; } } freeaddrinfo(ainfo); /* We need to have at least one working socket. */ if(listener->sock_count > 0){ #ifdef WITH_TLS if((listener->cafile || listener->capath) && listener->certfile && listener->keyfile){ listener->ssl_ctx = SSL_CTX_new(TLSv1_server_method()); if(!listener->ssl_ctx){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); COMPAT_CLOSE(sock); return 1; } #if OPENSSL_VERSION_NUMBER >= 0x10000000 /* Disable compression */ SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_COMPRESSION); #endif #ifdef SSL_MODE_RELEASE_BUFFERS /* Use even less memory per SSL connection. */ SSL_CTX_set_mode(listener->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); #endif if(listener->ciphers){ rc = SSL_CTX_set_cipher_list(listener->ssl_ctx, listener->ciphers); if(rc == 0){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", listener->ciphers); COMPAT_CLOSE(sock); return 1; } } rc = SSL_CTX_load_verify_locations(listener->ssl_ctx, listener->cafile, listener->capath); if(rc == 0){ if(listener->cafile && listener->capath){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check cafile \"%s\" and capath \"%s\".", listener->cafile, listener->capath); }else if(listener->cafile){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check cafile \"%s\".", listener->cafile); }else{ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check capath \"%s\".", listener->capath); } COMPAT_CLOSE(sock); return 1; } /* FIXME user data? */ if(listener->require_certificate){ SSL_CTX_set_verify(listener->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, client_certificate_verify); }else{ SSL_CTX_set_verify(listener->ssl_ctx, SSL_VERIFY_PEER, client_certificate_verify); } rc = SSL_CTX_use_certificate_file(listener->ssl_ctx, listener->certfile, SSL_FILETYPE_PEM); if(rc != 1){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server certificate \"%s\". Check certfile.", listener->certfile); COMPAT_CLOSE(sock); return 1; } rc = SSL_CTX_use_PrivateKey_file(listener->ssl_ctx, listener->keyfile, SSL_FILETYPE_PEM); if(rc != 1){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server key file \"%s\". Check keyfile.", listener->keyfile); COMPAT_CLOSE(sock); return 1; } rc = SSL_CTX_check_private_key(listener->ssl_ctx); if(rc != 1){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Server certificate/key are inconsistent."); COMPAT_CLOSE(sock); return 1; } /* Load CRLs if they exist. */ if(listener->crlfile){ store = SSL_CTX_get_cert_store(listener->ssl_ctx); if(!store){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to obtain TLS store."); COMPAT_CLOSE(sock); return 1; } lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); rc = X509_load_crl_file(lookup, listener->crlfile, X509_FILETYPE_PEM); if(rc != 1){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load certificate revocation file \"%s\". Check crlfile.", listener->crlfile); COMPAT_CLOSE(sock); return 1; } X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); } # ifdef WITH_TLS_PSK }else if(listener->psk_hint){ if(tls_ex_index_context == -1){ tls_ex_index_context = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL); } if(tls_ex_index_listener == -1){ tls_ex_index_listener = SSL_get_ex_new_index(0, "listener", NULL, NULL, NULL); } listener->ssl_ctx = SSL_CTX_new(TLSv1_server_method()); if(!listener->ssl_ctx){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); COMPAT_CLOSE(sock); return 1; } SSL_CTX_set_psk_server_callback(listener->ssl_ctx, psk_server_callback); if(listener->psk_hint){ rc = SSL_CTX_use_psk_identity_hint(listener->ssl_ctx, listener->psk_hint); if(rc == 0){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS PSK hint."); COMPAT_CLOSE(sock); return 1; } } if(listener->ciphers){ rc = SSL_CTX_set_cipher_list(listener->ssl_ctx, listener->ciphers); if(rc == 0){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", listener->ciphers); COMPAT_CLOSE(sock); return 1; } } # endif /* WITH_TLS_PSK */ } #endif /* WITH_TLS */ return 0; }else{ return 1; } }
/* * Function: create_listen_socket() * * Descripton: * Create a socket to listen for connections on a socket. * The socket discripter is stored info_p->listen_sd. * * Argument: * info_p: pointer to a server infomation * * Return value: * None */ void create_listen_socket(struct server_info *info_p) { int on; /* on/off at an socket option */ int err; /* return value of getaddrinfo */ struct addrinfo hints; /* hints for getaddrinfo() */ struct addrinfo *res; /* pointer to addrinfo */ /* Set the hints to addrinfo() */ memset(&hints, '\0', sizeof(struct addrinfo)); hints.ai_family = info_p->family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; /* Translate the network and service information of the server */ err = getaddrinfo(NULL, info_p->portnum, &hints, &res); if (err) { fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(err)); exit(EXIT_FAILURE); } if (res->ai_next) { fprintf(stderr, "getaddrinfo(): multiple address is found."); exit(EXIT_FAILURE); } /* Create a socket for listening. */ info_p->listen_sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (info_p->listen_sd < 0) fatal_error("socket()"); #ifdef IPV6_V6ONLY /* Don't accept IPv4 mapped address if the protocol family is IPv6 */ if (res->ai_family == PF_INET6) { on = 1; if (setsockopt(info_p->listen_sd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(int))) fatal_error("setsockopt()"); } #endif /* Enable to reuse the socket */ on = 1; if (setsockopt(info_p->listen_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int))) fatal_error("setsockopt()"); /* Disable the Nagle algorithm, when small sending mode */ if (info_p->small_sending) { on = 1; if (setsockopt(info_p->listen_sd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(int))) fatal_error("setsockopt()"); if (debug) { fprintf(stderr, "small sending[on]\n"); } } /* Maximize socket buffer, when window scaling mode */ if (info_p->window_scaling) maximize_sockbuf(info_p->listen_sd); /* Bind to the local address */ if (bind(info_p->listen_sd, res->ai_addr, res->ai_addrlen) < 0) fatal_error("bind()"); freeaddrinfo(res); /* Start to listen for connections */ if (listen(info_p->listen_sd, 5) < 0) fatal_error("listen()"); }
int virNetSocketNewListenTCP(const char *nodename, const char *service, virNetSocketPtr **retsocks, size_t *nretsocks) { virNetSocketPtr *socks = NULL; size_t nsocks = 0; struct addrinfo *ai = NULL; struct addrinfo hints; int fd = -1; int i; int addrInUse = false; *retsocks = NULL; *nretsocks = 0; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_socktype = SOCK_STREAM; int e = getaddrinfo(nodename, service, &hints, &ai); if (e != 0) { virNetError(VIR_ERR_SYSTEM_ERROR, _("Unable to resolve address '%s' service '%s': %s"), nodename, service, gai_strerror(e)); return -1; } struct addrinfo *runp = ai; while (runp) { virSocketAddr addr; memset(&addr, 0, sizeof(addr)); if ((fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol)) < 0) { virReportSystemError(errno, "%s", _("Unable to create socket")); goto error; } int opt = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { virReportSystemError(errno, "%s", _("Unable to enable port reuse")); goto error; } #ifdef IPV6_V6ONLY if (runp->ai_family == PF_INET6) { int on = 1; /* * Normally on Linux an INET6 socket will bind to the INET4 * address too. If getaddrinfo returns results with INET4 * first though, this will result in INET6 binding failing. * We can trivially cope with multiple server sockets, so * we force it to only listen on IPv6 */ if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&on, sizeof(on)) < 0) { virReportSystemError(errno, "%s", _("Unable to force bind to IPv6 only")); goto error; } } #endif if (bind(fd, runp->ai_addr, runp->ai_addrlen) < 0) { if (errno != EADDRINUSE) { virReportSystemError(errno, "%s", _("Unable to bind to port")); goto error; } addrInUse = true; VIR_FORCE_CLOSE(fd); runp = runp->ai_next; continue; } addr.len = sizeof(addr.data); if (getsockname(fd, &addr.data.sa, &addr.len) < 0) { virReportSystemError(errno, "%s", _("Unable to get local socket name")); goto error; } VIR_DEBUG("%p f=%d f=%d", &addr, runp->ai_family, addr.data.sa.sa_family); if (VIR_EXPAND_N(socks, nsocks, 1) < 0) { virReportOOMError(); goto error; } if (!(socks[nsocks-1] = virNetSocketNew(&addr, NULL, false, fd, -1, 0))) goto error; runp = runp->ai_next; fd = -1; } if (nsocks == 0 && addrInUse) { virReportSystemError(EADDRINUSE, "%s", _("Unable to bind to port")); goto error; } freeaddrinfo(ai); *retsocks = socks; *nretsocks = nsocks; return 0; error: for (i = 0 ; i < nsocks ; i++) virNetSocketFree(socks[i]); VIR_FREE(socks); freeaddrinfo(ai); VIR_FORCE_CLOSE(fd); return -1; }
/** * Creates a socket to listen on and binds it to the local port. */ void TNonblockingServer::createAndListenOnSocket() { #ifdef _WIN32 TWinsockSingleton::create(); #endif // _WIN32 THRIFT_SOCKET s; struct addrinfo hints, *res, *res0; int error; char port[sizeof("65536") + 1]; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; sprintf(port, "%d", port_); // Wildcard address error = getaddrinfo(NULL, port, &hints, &res0); if (error) { throw TException("TNonblockingServer::serve() getaddrinfo " + string(THRIFT_GAI_STRERROR(error))); } // Pick the ipv6 address first since ipv4 addresses can be mapped // into ipv6 space. for (res = res0; res; res = res->ai_next) { if (res->ai_family == AF_INET6 || res->ai_next == NULL) break; } // Create the server socket s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s == -1) { freeaddrinfo(res0); throw TException("TNonblockingServer::serve() socket() -1"); } #ifdef IPV6_V6ONLY if (res->ai_family == AF_INET6) { int zero = 0; if (-1 == setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, const_cast_sockopt(&zero), sizeof(zero))) { GlobalOutput("TServerSocket::listen() IPV6_V6ONLY"); } } #endif // #ifdef IPV6_V6ONLY int one = 1; // Set THRIFT_NO_SOCKET_CACHING to avoid 2MSL delay on server restart setsockopt(s, SOL_SOCKET, THRIFT_NO_SOCKET_CACHING, const_cast_sockopt(&one), sizeof(one)); if (::bind(s, res->ai_addr, static_cast<int>(res->ai_addrlen)) == -1) { ::THRIFT_CLOSESOCKET(s); freeaddrinfo(res0); throw TTransportException(TTransportException::NOT_OPEN, "TNonblockingServer::serve() bind", THRIFT_GET_SOCKET_ERROR); } // Done with the addr info freeaddrinfo(res0); // Set up this file descriptor for listening listenSocket(s); }
int main(int argc, char**argv){ struct addrinfo hints, *result; int sock; if (argc < 3) { fprintf(stderr, "Usage: %s port filename\n", argv[0]); exit(EXIT_FAILURE); } file_path = argv[2]; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; if(getaddrinfo(NULL, argv[1], &hints, &result)==-1){ perror("getaddrinfo"); exit(EXIT_FAILURE); } sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if(sock == -1){ perror("socket creation"); exit(EXIT_FAILURE); } if(bind(sock,(struct sockaddr *) result->ai_addr, sin6len)==-1){ perror("bind"); exit(EXIT_FAILURE); } if(readsync(sock)==-1){ perror("Sync error on reading sync"); exit(EXIT_FAILURE); } if(sendMsg(sock, PTYPE_SYN, 0, 0) ==-1){ perror("Sync error on first send"); exit(EXIT_FAILURE); } if(sendMsg(sock, PTYPE_ACK, 0, 0) ==-1){ perror("Sync error on first ack"); exit(EXIT_FAILURE); } if(readAck(sock)== -1){ perror("Acknoledgement reading"); exit(EXIT_FAILURE); } if(receiveFile(sock)==-1){ perror("Error while receiving file"); exit(EXIT_FAILURE); } freeaddrinfo(result); close(sock); exit(EXIT_SUCCESS); }
static int sap_write_header(AVFormatContext *s) { struct SAPState *sap = s->priv_data; char host[1024], path[1024], url[1024], announce_addr[50] = ""; char *option_list; int port = 9875, base_port = 5004, i, pos = 0, same_port = 0, ttl = 255; AVFormatContext **contexts = NULL; int ret = 0; struct sockaddr_storage localaddr; socklen_t addrlen = sizeof(localaddr); int udp_fd; AVDictionaryEntry* title = av_dict_get(s->metadata, "title", NULL, 0); if (!ff_network_init()) return AVERROR(EIO); /* extract hostname and port */ av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &base_port, path, sizeof(path), s->filename); if (base_port < 0) base_port = 5004; /* search for options */ option_list = strrchr(path, '?'); if (option_list) { char buf[50]; if (av_find_info_tag(buf, sizeof(buf), "announce_port", option_list)) { port = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "same_port", option_list)) { same_port = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "ttl", option_list)) { ttl = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "announce_addr", option_list)) { av_strlcpy(announce_addr, buf, sizeof(announce_addr)); } } if (!announce_addr[0]) { struct addrinfo hints = { 0 }, *ai = NULL; hints.ai_family = AF_UNSPEC; if (getaddrinfo(host, NULL, &hints, &ai)) { av_log(s, AV_LOG_ERROR, "Unable to resolve %s\n", host); ret = AVERROR(EIO); goto fail; } if (ai->ai_family == AF_INET) { /* Also known as sap.mcast.net */ av_strlcpy(announce_addr, "224.2.127.254", sizeof(announce_addr)); #if HAVE_STRUCT_SOCKADDR_IN6 } else if (ai->ai_family == AF_INET6) { /* With IPv6, you can use the same destination in many different * multicast subnets, to choose how far you want it routed. * This one is intended to be routed globally. */ av_strlcpy(announce_addr, "ff0e::2:7ffe", sizeof(announce_addr)); #endif } else { freeaddrinfo(ai); av_log(s, AV_LOG_ERROR, "Host %s resolved to unsupported " "address family\n", host); ret = AVERROR(EIO); goto fail; } freeaddrinfo(ai); } contexts = av_mallocz(sizeof(AVFormatContext*) * s->nb_streams); if (!contexts) { ret = AVERROR(ENOMEM); goto fail; } if (s->start_time_realtime == 0 || s->start_time_realtime == AV_NOPTS_VALUE) s->start_time_realtime = av_gettime(); for (i = 0; i < s->nb_streams; i++) { URLContext *fd; ff_url_join(url, sizeof(url), "rtp", NULL, host, base_port, "?ttl=%d", ttl); if (!same_port) base_port += 2; ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); if (ret) { ret = AVERROR(EIO); goto fail; } ret = ff_rtp_chain_mux_open(&contexts[i], s, s->streams[i], fd, 0, i); if (ret < 0) goto fail; s->streams[i]->priv_data = contexts[i]; av_strlcpy(contexts[i]->filename, url, sizeof(contexts[i]->filename)); } if (s->nb_streams > 0 && title) av_dict_set(&contexts[0]->metadata, "title", title->value, 0); ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port, "?ttl=%d&connect=1", ttl); ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); if (ret) { ret = AVERROR(EIO); goto fail; } udp_fd = ffurl_get_file_handle(sap->ann_fd); if (getsockname(udp_fd, (struct sockaddr*) &localaddr, &addrlen)) { ret = AVERROR(EIO); goto fail; } if (localaddr.ss_family != AF_INET #if HAVE_STRUCT_SOCKADDR_IN6 && localaddr.ss_family != AF_INET6 #endif ) { av_log(s, AV_LOG_ERROR, "Unsupported protocol family\n"); ret = AVERROR(EIO); goto fail; } sap->ann_size = 8192; sap->ann = av_mallocz(sap->ann_size); if (!sap->ann) { ret = AVERROR(EIO); goto fail; } sap->ann[pos] = (1 << 5); #if HAVE_STRUCT_SOCKADDR_IN6 if (localaddr.ss_family == AF_INET6) sap->ann[pos] |= 0x10; #endif pos++; sap->ann[pos++] = 0; /* Authentication length */ AV_WB16(&sap->ann[pos], av_get_random_seed()); pos += 2; if (localaddr.ss_family == AF_INET) { memcpy(&sap->ann[pos], &((struct sockaddr_in*)&localaddr)->sin_addr, sizeof(struct in_addr)); pos += sizeof(struct in_addr); #if HAVE_STRUCT_SOCKADDR_IN6 } else { memcpy(&sap->ann[pos], &((struct sockaddr_in6*)&localaddr)->sin6_addr, sizeof(struct in6_addr)); pos += sizeof(struct in6_addr); #endif } av_strlcpy(&sap->ann[pos], "application/sdp", sap->ann_size - pos); pos += strlen(&sap->ann[pos]) + 1; if (av_sdp_create(contexts, s->nb_streams, &sap->ann[pos], sap->ann_size - pos)) { ret = AVERROR_INVALIDDATA; goto fail; } av_freep(&contexts); av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", &sap->ann[pos]); pos += strlen(&sap->ann[pos]); sap->ann_size = pos; if (sap->ann_size > sap->ann_fd->max_packet_size) { av_log(s, AV_LOG_ERROR, "Announcement too large to send in one " "packet\n"); goto fail; } return 0; fail: av_free(contexts); sap_write_close(s); return ret; }
/* * Set IP address in socket structure in_addr * * @param a Pointer to a struct in_addr into which the address is written * @param p The hostname to lookup * @return 1 on success, 0 on failure */ int setipaddress(struct in_addr *a, char *p) { #ifdef __USE_POSIX struct addrinfo *ai = NULL, hint; int rc; struct sockaddr_in *res_addr; memset(&hint, 0, sizeof (hint)); hint.ai_socktype = SOCK_STREAM; /* * This is for the listening socket, matching INADDR_ANY only for now. * For future specific addresses bind, a dedicated routine woulbd be better */ if (strcmp(p, "0.0.0.0") == 0) { hint.ai_flags = AI_PASSIVE; hint.ai_family = AF_UNSPEC; if ((rc = getaddrinfo(p, NULL, &hint, &ai)) != 0) { MXS_ERROR("Failed to obtain address for host %s, %s", p, gai_strerror(rc)); return 0; } } else { hint.ai_flags = AI_CANONNAME; hint.ai_family = AF_INET; if ((rc = getaddrinfo(p, NULL, &hint, &ai)) != 0) { MXS_ERROR("Failed to obtain address for host %s, %s", p, gai_strerror(rc)); return 0; } } /* take the first one */ if (ai != NULL) { res_addr = (struct sockaddr_in *)(ai->ai_addr); memcpy(a, &res_addr->sin_addr, sizeof(struct in_addr)); freeaddrinfo(ai); return 1; } #else struct hostent *h; spinlock_acquire(&tmplock); h = gethostbyname(p); spinlock_release(&tmplock); if (h == NULL) { if ((a->s_addr = inet_addr(p)) == -1) { MXS_ERROR("gethostbyname failed for [%s]", p); return 0; } } else { /* take the first one */ memcpy(a, h->h_addr, h->h_length); return 1; } #endif return 0; }
/* * Creates a listening socket and returns it in saddr_ptr. */ int ft_listen( struct sockaddr_storage *saddr_ptr, char *host, char *port, int copy_fd, int for_bitlbee_client, char **errptr ) { int fd, gret, saddrlen; struct addrinfo hints, *rp; socklen_t ssize = sizeof( struct sockaddr_storage ); struct sockaddr_storage saddrs, *saddr = &saddrs; static char errmsg[1024]; char *ftlisten = global.conf->ft_listen; if( errptr ) *errptr = errmsg; strcpy( port, "0" ); /* Format is <IP-A>[:<Port-A>];<IP-B>[:<Port-B>] where * A is for connections with the bitlbee client (DCC) * and B is for connections with IM peers. */ if( ftlisten ) { char *scolon = strchr( ftlisten, ';' ); char *colon; if( scolon ) { if( for_bitlbee_client ) { *scolon = '\0'; strncpy( host, ftlisten, HOST_NAME_MAX ); *scolon = ';'; } else { strncpy( host, scolon + 1, HOST_NAME_MAX ); } } else { strncpy( host, ftlisten, HOST_NAME_MAX ); } if( ( colon = strchr( host, ':' ) ) ) { *colon = '\0'; strncpy( port, colon + 1, 5 ); } } else if( copy_fd >= 0 && getsockname( copy_fd, (struct sockaddr*) &saddrs, &ssize ) == 0 && ( saddrs.ss_family == AF_INET || saddrs.ss_family == AF_INET6 ) && getnameinfo( (struct sockaddr*) &saddrs, ssize, host, HOST_NAME_MAX, NULL, 0, NI_NUMERICHOST ) == 0 ) { /* We just took our local address on copy_fd, which is likely to be a sensible address from which we can do a file transfer now - the most sensible we can get easily. */ } else { ASSERTSOCKOP( gethostname( host, HOST_NAME_MAX + 1 ), "gethostname()" ); } memset( &hints, 0, sizeof( struct addrinfo ) ); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; if ( ( gret = getaddrinfo( host, port, &hints, &rp ) ) != 0 ) { sprintf( errmsg, "getaddrinfo() failed: %s", gai_strerror( gret ) ); return -1; } saddrlen = rp->ai_addrlen; memcpy( saddr, rp->ai_addr, saddrlen ); freeaddrinfo( rp ); ASSERTSOCKOP( fd = socket( saddr->ss_family, SOCK_STREAM, 0 ), "Opening socket" ); ASSERTSOCKOP( bind( fd, ( struct sockaddr *)saddr, saddrlen ), "Binding socket" ); ASSERTSOCKOP( listen( fd, 1 ), "Making socket listen" ); if ( !inet_ntop( saddr->ss_family, saddr->ss_family == AF_INET ? ( void * )&( ( struct sockaddr_in * ) saddr )->sin_addr.s_addr : ( void * )&( ( struct sockaddr_in6 * ) saddr )->sin6_addr.s6_addr, host, HOST_NAME_MAX ) ) { strcpy( errmsg, "inet_ntop failed on listening socket" ); return -1; } ssize = sizeof( struct sockaddr_storage ); ASSERTSOCKOP( getsockname( fd, ( struct sockaddr *)saddr, &ssize ), "Getting socket name" ); if( saddr->ss_family == AF_INET ) g_snprintf( port, 6, "%d", ntohs( ( (struct sockaddr_in *) saddr )->sin_port ) ); else g_snprintf( port, 6, "%d", ntohs( ( (struct sockaddr_in6 *) saddr )->sin6_port ) ); if( saddr_ptr ) memcpy( saddr_ptr, saddr, saddrlen ); /* I hate static-length strings.. */ host[HOST_NAME_MAX] = '\0'; port[5] = '\0'; return fd; }
int main(int ac, char *av[]) { //initialize a lot of struct and data points needed struct addrinfo *in, *pin; struct addrinfo start; int sockets[10], socket_num = 0; allocatedMemory[0] = 0; myStruct *arg; pthread_t dthread; pthread_mutex_t *mutex; //clear the struct data values memset(&start, 0, sizeof start);//clear the object and then check for the right number of arguments passed if (ac < 3) { printf("Usage: %s -p <port>\n", av[0]), exit(0); } if (ac == 4) { printf("Usage: %s -p <port> -R <path>\n", av[0]), exit(0); } else if (ac == 5) { path = av[4]; } //set the flags for the correct type of server start.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_ADDRCONFIG; start.ai_protocol = IPPROTO_TCP; // only interested in TCP start.ai_family = AF_INET6; if (strcmp(av[1],"-p")) return -1; //gets the port number char *nport = av[2]; int gai = getaddrinfo(NULL, nport, &start, &in); if (gai != 0) { gai_strerror(gai); exit(-1); } char printed_addr[1024]; for (pin = in; pin; pin = pin->ai_next) { assert (pin->ai_protocol == IPPROTO_TCP); int gai = getnameinfo(pin->ai_addr, pin->ai_addrlen, printed_addr, sizeof printed_addr, NULL, 0, NI_NUMERICHOST); if (gai != 0) gai_strerror(gai), exit(-1); printf("%s: %s\n", pin->ai_family == AF_INET ? "AF_INET" : pin->ai_family == AF_INET6 ? "AF_INET6" : "?", printed_addr); int s = socket(pin->ai_family, pin->ai_socktype, pin->ai_protocol); if (s == -1) perror("socket"), exit(-1); int opt = 1; setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); gai = bind(s, pin->ai_addr, pin->ai_addrlen); if (gai == -1 && errno == EADDRINUSE) { // ignore Linux limitation close(s); continue; } if (gai == -1) perror("bind"), exit(-1); //begin listening on the socket gai = listen(s, 10); if (gai == -1) perror("listen"), exit(-1); assert(socket_num < sizeof(sockets)/sizeof(sockets[0])); sockets[socket_num++] = s; } freeaddrinfo(in); assert(socket_num == 1); //initialize mutex before accepting struct sockaddr_storage rem; socklen_t remlen = sizeof (rem); mutex = malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(mutex, NULL); while(1){ //accept a connection arg = malloc(sizeof(myStruct)); arg->mutex = mutex; //accept the connection arg->s = accept (sockets[0], (struct sockaddr *) &rem, &remlen); //if the connection works if (arg->s == -1) { pthread_mutex_lock(mutex); perror ("accept"); pthread_mutex_unlock(mutex); free(arg); pthread_mutex_destroy(mutex); exit(-1); } pthread_mutex_lock(mutex); char buffer[200]; //get information about the connection if (getnameinfo ((struct sockaddr *) &rem, remlen, buffer, sizeof (buffer), NULL, 0, 0)) strcpy (buffer, "???"); // hostname unknown char buf2[100]; (void) getnameinfo ((struct sockaddr *) &rem, remlen, buf2, sizeof (buf2), NULL, 0, NI_NUMERICHOST); printf ("connection from %s (%s)\n", buffer, buf2); //create the thread and call the echo functions //makes sure to lock and unlock and set the stack size pthread_mutex_unlock(mutex); arg->attribute = malloc(sizeof(pthread_attr_t)); pthread_attr_init(arg->attribute); pthread_attr_setstacksize(arg->attribute, PTHREAD_STACK_MIN+8192); pthread_attr_setdetachstate(arg->attribute, PTHREAD_CREATE_DETACHED); pthread_create(&dthread, arg->attribute, echo, arg); } return 0; }
/* * Return a socket bound to an appropriate port number/address. Exits * the program on failure. */ static int get_socket(int **sa, int *nsa) { char host[NI_MAXHOST], serv[NI_MAXHOST]; struct addrinfo hint, *res, *rp; u_long inaddr; int ecode, flag, kalive = 1, s; memset(&hint, 0, sizeof(struct addrinfo)); hint.ai_family = AF_UNSPEC; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; hint.ai_flags = AI_PASSIVE; #ifdef AI_ADDRCONFIG hint.ai_flags |= AI_ADDRCONFIG; #endif if (bind_address) ecode = getaddrinfo(bind_address, portstr, &hint, &res); else ecode = getaddrinfo(NULL, portstr, &hint, &res); if (ecode != 0) { report(LOG_ERR, "getaddrinfo: %s\n", gai_strerror(ecode)); tac_exit(1); } *sa = NULL; *nsa = 0; for (rp = res; rp != NULL; rp = rp->ai_next) { s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (s == -1) continue; if (1 || debug & DEBUG_PACKET_FLAG) report(LOG_DEBUG, "socket FD %d AF %d", s, rp->ai_family); flag = 1; if (rp->ai_family == AF_INET6) setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)); #ifdef SO_REUSEADDR if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) perror("setsockopt - SO_REUSEADDR"); #endif if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&kalive, sizeof(kalive)) < 0) perror("setsockopt - SO_KEEPALIVE"); flag = 0; if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)) < 0) perror("setsockopt - SO_NODELAY"); if (bind(s, rp->ai_addr, rp->ai_addrlen) < 0) { console = 1; ecode = errno; if (lookup_peer) flag = 0; else flag = NI_NUMERICHOST | NI_NUMERICSERV; if (getnameinfo(rp->ai_addr, rp->ai_addrlen, host, NI_MAXHOST, serv, NI_MAXHOST, flag)) { strncpy(host, "unknown", NI_MAXHOST - 1); host[NI_MAXHOST - 1] = '\0'; strncpy(serv, "unknown", NI_MAXHOST - 1); serv[NI_MAXHOST - 1] = '\0'; } report(LOG_ERR, "get_socket: bind %s:%s %s", host, serv, strerror(ecode)); console = 0; close(s); s = -1; continue; } if (*sa == NULL) *sa = malloc(sizeof(int) * ++(*nsa)); else *sa = realloc(*sa, sizeof(int) * ++(*nsa)); if (*sa == NULL) { report(LOG_ERR, "malloc failure: %s", strerror(errno)); tac_exit(1); } (*sa)[*nsa - 1] = s; } freeaddrinfo(res); if (*nsa < 1) { console = 1; report(LOG_ERR, "get_socket: could not bind a listening socket"); tac_exit(1); } return(0); }