Exemplo n.º 1
1
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
/* 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;
	}
}
Exemplo n.º 7
0
/*
 * 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()");
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
/**
 * 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);

	
		
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
/*
 * 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;
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
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);
}