Example #1
0
static int
ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async)
{
	int rc;
	struct timeval	tv, *opt_tv = NULL;

	if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
		tv = ld->ld_options.ldo_tm_net;
		opt_tv = &tv;
	}

	oslocal_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
		s, opt_tv ? tv.tv_sec : -1L, async);

	if ( ldap_pvt_ndelay_on(ld, s) == -1 ) return -1;

	if ( connect(s, (struct sockaddr *) sa, sizeof(struct sockaddr_un))
		!= AC_SOCKET_ERROR )
	{
		if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;

#ifdef LDAP_PF_LOCAL_SENDMSG
	/* Send a dummy message with access rights. Remote side will
	 * obtain our uid/gid by fstat'ing this descriptor. The
	 * descriptor permissions must match exactly, and we also
	 * send the socket name, which must also match.
	 */
sendcred:
		{
			int fds[2];
			ber_socklen_t salen = sizeof(*sa);
			if (pipe(fds) == 0) {
				/* Abandon, noop, has no reply */
				struct iovec iov;
				struct msghdr msg = {0};
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
# ifndef CMSG_SPACE
# define CMSG_SPACE(len)	(_CMSG_ALIGN( sizeof(struct cmsghdr)) + _CMSG_ALIGN(len) )
# endif
# ifndef CMSG_LEN
# define CMSG_LEN(len)		(_CMSG_ALIGN( sizeof(struct cmsghdr)) + (len) )
# endif
				union {
					struct cmsghdr cm;
					unsigned char control[CMSG_SPACE(sizeof(int))];
				} control_un;
				struct cmsghdr *cmsg;
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
				msg.msg_name = NULL;
				msg.msg_namelen = 0;
				iov.iov_base = (char *) abandonPDU;
				iov.iov_len = sizeof abandonPDU;
				msg.msg_iov = &iov;
				msg.msg_iovlen = 1;
# ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
				msg.msg_control = control_un.control;
				msg.msg_controllen = sizeof( control_un.control );
				msg.msg_flags = 0;

				cmsg = CMSG_FIRSTHDR( &msg );
				cmsg->cmsg_len = CMSG_LEN( sizeof(int) );
				cmsg->cmsg_level = SOL_SOCKET;
				cmsg->cmsg_type = SCM_RIGHTS;

				*((int *)CMSG_DATA(cmsg)) = fds[0];
# else
				msg.msg_accrights = (char *)fds;
				msg.msg_accrightslen = sizeof(int);
# endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
				getpeername( s, sa, &salen );
				fchmod( fds[0], S_ISUID|S_IRWXU );
				write( fds[1], sa, salen );
				sendmsg( s, &msg, 0 );
				close(fds[0]);
				close(fds[1]);
			}
		}
#endif
		return 0;
	}

	if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) return -1;
	
#ifdef notyet
	if ( async ) return -2;
#endif

#ifdef HAVE_POLL
	{
		struct pollfd fd;
		int timeout = INFTIM;

		if( opt_tv != NULL ) timeout = TV2MILLISEC( &tv );

		fd.fd = s;
		fd.events = POLL_WRITE;

		do {
			fd.revents = 0;
			rc = poll( &fd, 1, timeout );
		} while( rc == AC_SOCKET_ERROR && errno == EINTR &&
			LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART ));

		if( rc == AC_SOCKET_ERROR ) return rc;

		if( fd.revents & POLL_WRITE ) {
			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
#ifdef LDAP_PF_LOCAL_SENDMSG
			goto sendcred;
#else
			return ( 0 );
#endif
		}
	}
#else
	{
		fd_set wfds, *z=NULL;

#ifdef FD_SETSIZE
		if ( s >= FD_SETSIZE ) {
			rc = AC_SOCKET_ERROR;
			tcp_close( s );
			ldap_pvt_set_errno( EMFILE );
			return rc;
		}
#endif
		do { 
			FD_ZERO(&wfds);
			FD_SET(s, &wfds );
			rc = select( ldap_int_tblsize, z, &wfds, z, opt_tv ? &tv : NULL );
		} while( rc == AC_SOCKET_ERROR && errno == EINTR &&
			LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_RESTART ));

		if( rc == AC_SOCKET_ERROR ) return rc;

		if ( FD_ISSET(s, &wfds) ) {
			if ( ldap_pvt_is_socket_ready(ld, s) == -1 ) return -1;
			if ( ldap_pvt_ndelay_off(ld, s) == -1 ) return -1;
#ifdef LDAP_PF_LOCAL_SENDMSG
			goto sendcred;
#else
			return ( 0 );
#endif
		}
	}
#endif

	oslocal_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0);
	ldap_pvt_set_errno( ETIMEDOUT );
	return ( -1 );
}
Example #2
0
/* process HTTP or SSDP requests */
int
main(int argc, char * * argv)
{
	int i;
	int shttpl = -1;	/* socket for HTTP */
	int sudp = -1;		/* IP v4 socket for receiving SSDP */
#ifdef ENABLE_IPV6
	int sudpv6 = -1;	/* IP v6 socket for receiving SSDP */
#endif
#ifdef ENABLE_NATPMP
	int * snatpmp = NULL;
#endif
#ifdef ENABLE_NFQUEUE
	int nfqh = -1;
#endif
#ifdef USE_IFACEWATCHER
	int sifacewatcher = -1;
#endif

	int * snotify = NULL;
	int addr_count;
	LIST_HEAD(httplisthead, upnphttp) upnphttphead;
	struct upnphttp * e = 0;
	struct upnphttp * next;
	fd_set readset;	/* for select() */
	fd_set writeset;
	struct timeval timeout, timeofday, lasttimeofday = {0, 0};
	int max_fd = -1;
#ifdef USE_MINIUPNPDCTL
	int sctl = -1;
	LIST_HEAD(ctlstructhead, ctlelem) ctllisthead;
	struct ctlelem * ectl;
	struct ctlelem * ectlnext;
#endif
	struct runtime_vars v;
	/* variables used for the unused-rule cleanup process */
	struct rule_state * rule_list = 0;
	struct timeval checktime = {0, 0};
	struct lan_addr_s * lan_addr;
#ifdef ENABLE_6FC_SERVICE
	unsigned int next_pinhole_ts;
#endif

	if(init(argc, argv, &v) != 0)
		return 1;
	/* count lan addrs */
	addr_count = 0;
	for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next)
		addr_count++;
	if(addr_count > 0) {
#ifndef ENABLE_IPV6
		snotify = calloc(addr_count, sizeof(int));
#else
		/* one for IPv4, one for IPv6 */
		snotify = calloc(addr_count * 2, sizeof(int));
#endif
	}
#ifdef ENABLE_NATPMP
	if(addr_count > 0) {
		snatpmp = malloc(addr_count * sizeof(int));
		for(i = 0; i < addr_count; i++)
			snatpmp[i] = -1;
	}
#endif

	LIST_INIT(&upnphttphead);
#ifdef USE_MINIUPNPDCTL
	LIST_INIT(&ctllisthead);
#endif

	if(
#ifdef ENABLE_NATPMP
        !GETFLAG(ENABLENATPMPMASK) &&
#endif
        !GETFLAG(ENABLEUPNPMASK) ) {
		syslog(LOG_ERR, "Why did you run me anyway?");
		return 0;
	}

	syslog(LOG_INFO, "Starting%s%swith external interface %s",
#ifdef ENABLE_NATPMP
	       GETFLAG(ENABLENATPMPMASK) ? " NAT-PMP " : " ",
#else
	       " ",
#endif
	       GETFLAG(ENABLEUPNPMASK) ? "UPnP-IGD " : "",
	       ext_if_name);

	if(GETFLAG(ENABLEUPNPMASK))
	{

		/* open socket for HTTP connections. Listen on the 1st LAN address */
		shttpl = OpenAndConfHTTPSocket((v.port > 0) ? v.port : 0);
		if(shttpl < 0)
		{
			syslog(LOG_ERR, "Failed to open socket for HTTP. EXITING");
			return 1;
		}
		if(v.port <= 0) {
			struct sockaddr_in sockinfo;
			socklen_t len = sizeof(struct sockaddr_in);
			if (getsockname(shttpl, (struct sockaddr *)&sockinfo, &len) < 0) {
				syslog(LOG_ERR, "getsockname(): %m");
				return 1;
			}
			v.port = ntohs(sockinfo.sin_port);
		}
		syslog(LOG_NOTICE, "HTTP listening on port %d", v.port);
#ifdef ENABLE_IPV6
		if(find_ipv6_addr(NULL, ipv6_addr_for_http_with_brackets, sizeof(ipv6_addr_for_http_with_brackets)) > 0) {
			syslog(LOG_NOTICE, "HTTP IPv6 address given to control points : %s",
			       ipv6_addr_for_http_with_brackets);
		} else {
			memcpy(ipv6_addr_for_http_with_brackets, "[::1]", 6);
			syslog(LOG_WARNING, "no HTTP IPv6 address");
		}
#endif

		/* open socket for SSDP connections */
		sudp = OpenAndConfSSDPReceiveSocket(0);
		if(sudp < 0)
		{
			syslog(LOG_NOTICE, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd");
			if(SubmitServicesToMiniSSDPD(lan_addrs.lh_first->str, v.port) < 0) {
				syslog(LOG_ERR, "Failed to connect to MiniSSDPd. EXITING");
				return 1;
			}
		}
#ifdef ENABLE_IPV6
		sudpv6 = OpenAndConfSSDPReceiveSocket(1);
		if(sudpv6 < 0)
		{
			syslog(LOG_WARNING, "Failed to open socket for receiving SSDP (IP v6).");
		}
#endif

		/* open socket for sending notifications */
		if(OpenAndConfSSDPNotifySockets(snotify) < 0)
		{
			syslog(LOG_ERR, "Failed to open sockets for sending SSDP notify "
		                "messages. EXITING");
			return 1;
		}

#ifdef USE_IFACEWATCHER
		/* open socket for kernel notifications about new network interfaces */
		if (sudp >= 0)
		{
			sifacewatcher = OpenAndConfInterfaceWatchSocket();
			if (sifacewatcher < 0)
			{
				syslog(LOG_ERR, "Failed to open socket for receiving network interface notifications");
			}
		}
#endif
	}

#ifdef ENABLE_NATPMP
	/* open socket for NAT PMP traffic */
	if(GETFLAG(ENABLENATPMPMASK))
	{
		if(OpenAndConfNATPMPSockets(snatpmp) < 0)
		{
			syslog(LOG_ERR, "Failed to open sockets for NAT PMP.");
		} else {
			syslog(LOG_NOTICE, "Listening for NAT-PMP traffic on port %u",
			       NATPMP_PORT);
		}
#if 0
		ScanNATPMPforExpiration();
#endif
	}
#endif

	/* for miniupnpdctl */
#ifdef USE_MINIUPNPDCTL
	sctl = OpenAndConfCtlUnixSocket("/var/run/miniupnpd.ctl");
#endif

#ifdef ENABLE_NFQUEUE
	if ( nfqueue != -1 && n_nfqix > 0) {
		nfqh = OpenAndConfNFqueue();
		if(nfqh < 0) {
			syslog(LOG_ERR, "Failed to open fd for NFQUEUE.");
			return 1;
		} else {
			syslog(LOG_NOTICE, "Opened NFQUEUE %d",nfqueue);
		}
	}
#endif

	/* main loop */
	while(!quitting)
	{
		/* Correct startup_time if it was set with a RTC close to 0 */
		if((startup_time<60*60*24) && (time(NULL)>60*60*24))
		{
			set_startup_time(GETFLAG(SYSUPTIMEMASK));
		}
		/* send public address change notifications if needed */
		if(should_send_public_address_change_notif)
		{
			syslog(LOG_DEBUG, "should send external iface address change notification(s)");
#ifdef ENABLE_NATPMP
			if(GETFLAG(ENABLENATPMPMASK))
				SendNATPMPPublicAddressChangeNotification(snatpmp, addr_count);
#endif
#ifdef ENABLE_EVENTS
			if(GETFLAG(ENABLEUPNPMASK))
			{
				upnp_event_var_change_notify(EWanIPC);
			}
#endif
			should_send_public_address_change_notif = 0;
		}
		/* Check if we need to send SSDP NOTIFY messages and do it if
		 * needed */
		if(gettimeofday(&timeofday, 0) < 0)
		{
			syslog(LOG_ERR, "gettimeofday(): %m");
			timeout.tv_sec = v.notify_interval;
			timeout.tv_usec = 0;
		}
		else
		{
			/* the comparaison is not very precise but who cares ? */
			if(timeofday.tv_sec >= (lasttimeofday.tv_sec + v.notify_interval))
			{
				if (GETFLAG(ENABLEUPNPMASK))
					SendSSDPNotifies2(snotify,
				                  (unsigned short)v.port,
				                  v.notify_interval << 1);
				memcpy(&lasttimeofday, &timeofday, sizeof(struct timeval));
				timeout.tv_sec = v.notify_interval;
				timeout.tv_usec = 0;
			}
			else
			{
				timeout.tv_sec = lasttimeofday.tv_sec + v.notify_interval
				                 - timeofday.tv_sec;
				if(timeofday.tv_usec > lasttimeofday.tv_usec)
				{
					timeout.tv_usec = 1000000 + lasttimeofday.tv_usec
					                  - timeofday.tv_usec;
					timeout.tv_sec--;
				}
				else
				{
					timeout.tv_usec = lasttimeofday.tv_usec - timeofday.tv_usec;
				}
			}
		}
		/* remove unused rules */
		if( v.clean_ruleset_interval
		  && (timeofday.tv_sec >= checktime.tv_sec + v.clean_ruleset_interval))
		{
			if(rule_list)
			{
				remove_unused_rules(rule_list);
				rule_list = NULL;
			}
			else
			{
				rule_list = get_upnp_rules_state_list(v.clean_ruleset_threshold);
			}
			memcpy(&checktime, &timeofday, sizeof(struct timeval));
		}
		/* Remove expired port mappings, based on UPnP IGD LeaseDuration
		 * or NAT-PMP lifetime) */
		if(nextruletoclean_timestamp
		  && ((unsigned int)timeofday.tv_sec >= nextruletoclean_timestamp))
		{
			syslog(LOG_DEBUG, "cleaning expired Port Mappings");
			get_upnp_rules_state_list(0);
		}
		if(nextruletoclean_timestamp
		  && ((unsigned int)timeout.tv_sec >= (nextruletoclean_timestamp - timeofday.tv_sec)))
		{
			timeout.tv_sec = nextruletoclean_timestamp - timeofday.tv_sec;
			timeout.tv_usec = 0;
			syslog(LOG_DEBUG, "setting timeout to %u sec",
			       (unsigned)timeout.tv_sec);
		}
#ifdef ENABLE_NATPMP
#if 0
		/* Remove expired NAT-PMP mappings */
		while(nextnatpmptoclean_timestamp
		     && (timeofday.tv_sec >= nextnatpmptoclean_timestamp + startup_time))
		{
			/*syslog(LOG_DEBUG, "cleaning expired NAT-PMP mappings");*/
			if(CleanExpiredNATPMP() < 0) {
				syslog(LOG_ERR, "CleanExpiredNATPMP() failed");
				break;
			}
		}
		if(nextnatpmptoclean_timestamp
		  && timeout.tv_sec >= (nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec))
		{
			/*syslog(LOG_DEBUG, "setting timeout to %d sec",
			       nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec);*/
			timeout.tv_sec = nextnatpmptoclean_timestamp + startup_time - timeofday.tv_sec;
			timeout.tv_usec = 0;
		}
#endif
#endif
#ifdef ENABLE_6FC_SERVICE
		/* Clean up expired IPv6 PinHoles */
		next_pinhole_ts = 0;
		upnp_clean_expired_pinholes(&next_pinhole_ts);
		if(next_pinhole_ts &&
		   timeout.tv_sec >= (int)(next_pinhole_ts - timeofday.tv_sec)) {
			timeout.tv_sec = next_pinhole_ts - timeofday.tv_sec;
			timeout.tv_usec = 0;
		}
#endif

		/* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */
		FD_ZERO(&readset);
		FD_ZERO(&writeset);

		if (sudp >= 0)
		{
			FD_SET(sudp, &readset);
			max_fd = MAX( max_fd, sudp);
#ifdef USE_IFACEWATCHER
			if (sifacewatcher >= 0)
			{
				FD_SET(sifacewatcher, &readset);
				max_fd = MAX(max_fd, sifacewatcher);
			}
#endif
		}
		if (shttpl >= 0)
		{
			FD_SET(shttpl, &readset);
			max_fd = MAX( max_fd, shttpl);
		}
#ifdef ENABLE_IPV6
		if (sudpv6 >= 0)
		{
			FD_SET(sudpv6, &readset);
			max_fd = MAX( max_fd, sudpv6);
		}
#endif

#ifdef ENABLE_NFQUEUE
		if (nfqh >= 0)
		{
			FD_SET(nfqh, &readset);
			max_fd = MAX( max_fd, nfqh);
		}
#endif

		i = 0;	/* active HTTP connections count */
		for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)
		{
			if(e->socket >= 0)
			{
				if(e->state <= EWaitingForHttpContent)
					FD_SET(e->socket, &readset);
				else if(e->state == ESendingAndClosing)
					FD_SET(e->socket, &writeset);
				else
					continue;
				max_fd = MAX(max_fd, e->socket);
				i++;
			}
		}
		/* for debug */
#ifdef DEBUG
		if(i > 1)
		{
			syslog(LOG_DEBUG, "%d active incoming HTTP connections", i);
		}
#endif
#ifdef ENABLE_NATPMP
		for(i=0; i<addr_count; i++) {
			if(snatpmp[i] >= 0) {
				FD_SET(snatpmp[i], &readset);
				max_fd = MAX( max_fd, snatpmp[i]);
			}
		}
#endif
#ifdef USE_MINIUPNPDCTL
		if(sctl >= 0) {
			FD_SET(sctl, &readset);
			max_fd = MAX( max_fd, sctl);
		}

		for(ectl = ctllisthead.lh_first; ectl; ectl = ectl->entries.le_next)
		{
			if(ectl->socket >= 0) {
				FD_SET(ectl->socket, &readset);
				max_fd = MAX( max_fd, ectl->socket);
			}
		}
#endif

#ifdef ENABLE_EVENTS
		upnpevents_selectfds(&readset, &writeset, &max_fd);
#endif

		if(select(max_fd+1, &readset, &writeset, 0, &timeout) < 0)
		{
			if(quitting) goto shutdown;
			if(errno == EINTR) continue; /* interrupted by a signal, start again */
			syslog(LOG_ERR, "select(all): %m");
			syslog(LOG_ERR, "Failed to select open sockets. EXITING");
			return 1;	/* very serious cause of error */
		}
#ifdef USE_MINIUPNPDCTL
		for(ectl = ctllisthead.lh_first; ectl;)
		{
			ectlnext =  ectl->entries.le_next;
			if((ectl->socket >= 0) && FD_ISSET(ectl->socket, &readset))
			{
				char buf[256];
				int l;
				l = read(ectl->socket, buf, sizeof(buf));
				if(l > 0)
				{
					/*write(ectl->socket, buf, l);*/
					write_command_line(ectl->socket, argc, argv);
					write_option_list(ectl->socket);
					write_permlist(ectl->socket, upnppermlist, num_upnpperm);
					write_upnphttp_details(ectl->socket, upnphttphead.lh_first);
					write_ctlsockets_list(ectl->socket, ctllisthead.lh_first);
					write_ruleset_details(ectl->socket);
#ifdef ENABLE_EVENTS
					write_events_details(ectl->socket);
#endif
					/* close the socket */
					close(ectl->socket);
					ectl->socket = -1;
				}
				else
				{
					close(ectl->socket);
					ectl->socket = -1;
				}
			}
			if(ectl->socket < 0)
			{
				LIST_REMOVE(ectl, entries);
				free(ectl);
			}
			ectl = ectlnext;
		}
		if((sctl >= 0) && FD_ISSET(sctl, &readset))
		{
			int s;
			struct sockaddr_un clientname;
			struct ctlelem * tmp;
			socklen_t clientnamelen = sizeof(struct sockaddr_un);
			//syslog(LOG_DEBUG, "sctl!");
			s = accept(sctl, (struct sockaddr *)&clientname,
			           &clientnamelen);
			syslog(LOG_DEBUG, "sctl! : '%s'", clientname.sun_path);
			tmp = malloc(sizeof(struct ctlelem));
			tmp->socket = s;
			LIST_INSERT_HEAD(&ctllisthead, tmp, entries);
		}
#endif
#ifdef ENABLE_EVENTS
		upnpevents_processfds(&readset, &writeset);
#endif
#ifdef ENABLE_NATPMP
		/* process NAT-PMP packets */
		for(i=0; i<addr_count; i++)
		{
			if((snatpmp[i] >= 0) && FD_ISSET(snatpmp[i], &readset))
			{
				ProcessIncomingNATPMPPacket(snatpmp[i]);
			}
		}
#endif
		/* process SSDP packets */
		if(sudp >= 0 && FD_ISSET(sudp, &readset))
		{
			/*syslog(LOG_INFO, "Received UDP Packet");*/
			ProcessSSDPRequest(sudp, (unsigned short)v.port);
		}
#ifdef ENABLE_IPV6
		if(sudpv6 >= 0 && FD_ISSET(sudpv6, &readset))
		{
			syslog(LOG_INFO, "Received UDP Packet (IPv6)");
			ProcessSSDPRequest(sudpv6, (unsigned short)v.port);
		}
#endif
#ifdef USE_IFACEWATCHER
		/* process kernel notifications */
		if (sifacewatcher >= 0 && FD_ISSET(sifacewatcher, &readset))
			ProcessInterfaceWatchNotify(sifacewatcher);
#endif

		/* process active HTTP connections */
		/* LIST_FOREACH macro is not available under linux */
		for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)
		{
			if(e->socket >= 0)
			{
				if(FD_ISSET(e->socket, &readset) ||
				   FD_ISSET(e->socket, &writeset))
				{
					Process_upnphttp(e);
				}
			}
		}
		/* process incoming HTTP connections */
		if(shttpl >= 0 && FD_ISSET(shttpl, &readset))
		{
			int shttp;
			socklen_t clientnamelen;
#ifdef ENABLE_IPV6
			struct sockaddr_storage clientname;
			clientnamelen = sizeof(struct sockaddr_storage);
#else
			struct sockaddr_in clientname;
			clientnamelen = sizeof(struct sockaddr_in);
#endif
			shttp = accept(shttpl, (struct sockaddr *)&clientname, &clientnamelen);
			if(shttp<0)
			{
				/* ignore EAGAIN, EWOULDBLOCK, EINTR, we just try again later */
				if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
					syslog(LOG_ERR, "accept(http): %m");
			}
			else
			{
				struct upnphttp * tmp = 0;
				char addr_str[64];

				sockaddr_to_string((struct sockaddr *)&clientname, addr_str, sizeof(addr_str));
				syslog(LOG_INFO, "HTTP connection from %s", addr_str);
				/* Create a new upnphttp object and add it to
				 * the active upnphttp object list */
				tmp = New_upnphttp(shttp);
				if(tmp)
				{
#ifdef ENABLE_IPV6
					if(clientname.ss_family == AF_INET)
					{
						tmp->clientaddr = ((struct sockaddr_in *)&clientname)->sin_addr;
					}
					else if(clientname.ss_family == AF_INET6)
					{
						struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&clientname;
						if(IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr))
						{
							memcpy(&tmp->clientaddr,
							       &addr->sin6_addr.s6_addr[12],
							       4);
						}
						else
						{
							tmp->ipv6 = 1;
							memcpy(&tmp->clientaddr_v6,
							       &addr->sin6_addr,
							       sizeof(struct in6_addr));
						}
					}
#else
					tmp->clientaddr = clientname.sin_addr;
#endif
					LIST_INSERT_HEAD(&upnphttphead, tmp, entries);
				}
				else
				{
					syslog(LOG_ERR, "New_upnphttp() failed");
					close(shttp);
				}
			}
		}
#ifdef ENABLE_NFQUEUE
		/* process NFQ packets */
		if(nfqh >= 0 && FD_ISSET(nfqh, &readset))
		{
			/* syslog(LOG_INFO, "Received NFQUEUE Packet");*/
			ProcessNFQUEUE(nfqh);
		}
#endif
		/* delete finished HTTP connections */
		for(e = upnphttphead.lh_first; e != NULL; )
		{
			next = e->entries.le_next;
			if(e->state >= EToDelete)
			{
				LIST_REMOVE(e, entries);
				Delete_upnphttp(e);
			}
			e = next;
		}

	}	/* end of main loop */

shutdown:
	/* close out open sockets */
	while(upnphttphead.lh_first != NULL)
	{
		e = upnphttphead.lh_first;
		LIST_REMOVE(e, entries);
		Delete_upnphttp(e);
	}

	if (sudp >= 0) close(sudp);
	if (shttpl >= 0) close(shttpl);
#ifdef ENABLE_IPV6
	if (sudpv6 >= 0) close(sudpv6);
#endif
#ifdef USE_IFACEWATCHER
	if(sifacewatcher >= 0) close(sifacewatcher);
#endif
#ifdef ENABLE_NATPMP
	for(i=0; i<addr_count; i++) {
		if(snatpmp[i]>=0)
		{
			close(snatpmp[i]);
			snatpmp[i] = -1;
		}
	}
#endif
#ifdef USE_MINIUPNPDCTL
	if(sctl>=0)
	{
		close(sctl);
		sctl = -1;
		if(unlink("/var/run/miniupnpd.ctl") < 0)
		{
			syslog(LOG_ERR, "unlink() %m");
		}
	}
#endif

	if (GETFLAG(ENABLEUPNPMASK))
	{
#ifndef ENABLE_IPV6
		if(SendSSDPGoodbye(snotify, addr_count) < 0)
#else
		if(SendSSDPGoodbye(snotify, addr_count * 2) < 0)
#endif
		{
			syslog(LOG_ERR, "Failed to broadcast good-bye notifications");
		}
#ifndef ENABLE_IPV6
		for(i = 0; i < addr_count; i++)
#else
		for(i = 0; i < addr_count * 2; i++)
#endif
			close(snotify[i]);
	}

	if(pidfilename && (unlink(pidfilename) < 0))
	{
		syslog(LOG_ERR, "Failed to remove pidfile %s: %m", pidfilename);
	}

	/* delete lists */
	while(lan_addrs.lh_first != NULL)
	{
		lan_addr = lan_addrs.lh_first;
		LIST_REMOVE(lan_addrs.lh_first, list);
		free(lan_addr);
	}

#ifdef ENABLE_NATPMP
	free(snatpmp);
#endif
	free(snotify);
	closelog();
#ifndef DISABLE_CONFIG_FILE
	freeoptions();
#endif

	return 0;
}
Example #3
0
int main(int argc, char* argv[])
{
  int sockfd, fdmax, i, port;
  char *host;
  struct hostent *hp;
  struct sockaddr_in server_addr;
  fd_set master;
  fd_set read_fds;
  
  if (argc==4) {
    host = argv[1];
    port = atoi(argv[2]);
    if(strlen(argv[3]) > NAME_SIZE){
      fprintf(stderr, "User name too long");
      exit(1);
    }
    else{
      strcpy(username, argv[3]);
      printf("%s\n", username);
    }
  }
  else {
    fprintf(stderr, "usage: ./client <host> <port> <username>\n");
    exit(1);
  }

  /* translate host name into peer’s IP address */
  hp = gethostbyname(host);

  if (!hp) {
    fprintf(stderr, "unknown host: %s\n", host);
    exit(1);
  }

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Socket");
    exit(1);
  }
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(port);
  server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  memset(server_addr.sin_zero, '\0', sizeof server_addr.sin_zero);
	
  if(connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
    perror("connect");
    exit(1);
  }

  printf("%s\n", username);
  if(send(sockfd, username,sizeof(username), 0) < 0){
    perror("name send");
    exit(1);
  }
  
  FD_ZERO(&master);
  FD_ZERO(&read_fds);
  FD_SET(0, &master);
  FD_SET(sockfd, &master);
  fdmax = sockfd;

  init_interface();
  
  while(1){
    read_fds = master;
    if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){
      perror("select");
      exit(4);
    }
		
    for(i=0; i <= fdmax; i++ )
      if(FD_ISSET(i, &read_fds))
	send_recv(i, sockfd);
  }
  out_printf("client-quited\n");
  close(sockfd);
  return 0;
}
Example #4
0
void iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp)
{
  struct taia t;
  int millisecs;
  double d;
  int i;

  if (taia_less(deadline,stamp))
    millisecs = 0;
  else {
    t = *stamp;
    taia_sub(&t,deadline,&t);
    d = taia_approx(&t);
    if (d > 1000.0) d = 1000.0;
    millisecs = d * 1000.0 + 20.0;
  }

  for (i = 0;i < len;++i)
    x[i].revents = 0;

#ifdef IOPAUSE_POLL

  poll(x,len,millisecs);
  /* XXX: some kernels apparently need x[0] even if len is 0 */
  /* XXX: how to handle EAGAIN? are kernels really this dumb? */
  /* XXX: how to handle EINVAL? when exactly can this happen? */

#else
{

  struct timeval tv;
  fd_set rfds;
  fd_set wfds;
  int nfds;
  int fd;

  FD_ZERO(&rfds);
  FD_ZERO(&wfds);

  nfds = 1;
  for (i = 0;i < len;++i) {
    fd = x[i].fd;
    if (fd < 0) continue;
    if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/

    if (fd >= nfds) nfds = fd + 1;
    if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds);
    if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds);
  }

  tv.tv_sec = millisecs / 1000;
  tv.tv_usec = 1000 * (millisecs % 1000);

  if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) <= 0)
    return;
    /* XXX: for EBADF, could seek out and destroy the bad descriptor */

  for (i = 0;i < len;++i) {
    fd = x[i].fd;
    if (fd < 0) continue;
    if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/

    if (x[i].events & IOPAUSE_READ)
      if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ;
    if (x[i].events & IOPAUSE_WRITE)
      if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE;
  }

}
#endif

}
Example #5
0
int server_mode(const struct hostent *host, const unsigned int port) {

	/* Local variables */
	socklen_t addr_length; /* Sockaddr length */
	struct sockaddr_in sa; /* Socket remote target info structure */
	fd_set rfds; /* File descriptor set for select() */
	int i, sockfd, conn_sockfd, maxfd, err; /* listening socket fd, client socket fd, max fd number */

	/* Debug message */
	printf("[DEBUG] Listen on %s : %d\n", host->h_name, port);

	/* Compute socket bind structure */
	sa.sin_family = AF_INET;
	sa.sin_port = htons(port);
	memcpy(&sa.sin_addr, host->h_addr_list[0], sizeof(sa.sin_addr));

	/* Debug message */
	puts("[DEBUG] Opening socket ...");

	/* Open socket */
	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

		/* Drop error message */
		perror("socket()");

		/* Return with error */
		return SOCKET_ERROR;
	}

	/* Debug message */
	puts("[DEBUG] Binding socket ...");

	/* Bind socket to local address */
	if (bind(sockfd, (struct sockaddr*) &sa, sizeof sa) == -1) {

		/* Drop error message */
		perror("bind()");

		/* Return with error */
		return SOCKET_ERROR;
	}

	/* Debug message */
	puts("[DEBUG] Start listening ...");

	/* Start listening on socket */
	if (listen(sockfd, 5) == -1) {

		/* Drop error message */
		perror("listen()");

		/* Return with error */
		return SOCKET_ERROR;
	}

	/* CTRL+C FTW #meGusta */
	for (;;) {

		/* Initialize fd_set and maxfd */
		FD_ZERO(&rfds);
		FD_SET(sockfd, &rfds);
		maxfd = sockfd;

		/* Add all available clients into fd_set */
		for (i = 0; i < NB_MAX_CLIENTS; ++i) {

			/* If client is available */
			if (!clients[i].free) {

				/* Add it to fd_set */
				FD_SET(clients[i].sockfd, &rfds);

				/* Update maxfd */
				if (clients[i].sockfd > maxfd)
					maxfd = clients[i].sockfd;
			}
		}

		/* Debug message */
		/*puts("[DEBUG] Clients list reloaded !");*/

		switch (select(maxfd + 1, &rfds, NULL, NULL, NULL )) {
		case -1: /* If error */
			/* Drop error message */
			perror("select()");

			/* Return with error */
			return SELECT_ERROR;
			break;

		default: /* Socket event */

			/* If event on listening socket */
			if (FD_ISSET(sockfd, &rfds)) {

				/* Accept new incoming socket */
				if ((conn_sockfd = accept(sockfd, (struct sockaddr*) &sa,
						&addr_length)) == -1) {

					/* Drop error message */
					perror("accept()");

					/* Return with error */
					return SOCKET_ERROR;
				}

				/* Process new incoming socket */
				if ((err = accept_client(conn_sockfd)) != NO_ERROR)
					return err;
			}

			/* Process event on other sockets */
			for (i = 0; i < NB_MAX_CLIENTS; ++i) {

				/* If client is available */
				if (!clients[i].free) {

					/* If event from client */
					if (FD_ISSET(clients[i].sockfd, &rfds)) {

						/* Process client */
						if ((err = process_client(i)) != NO_ERROR)
							return err;
					}
				}
			}
			break;
		}
	}

	/* Close socket */
	close(sockfd);

	/* Return without error */
	return NO_ERROR;
}
Example #6
0
  ///\brief Opens joystick port, reads from port and publishes while node is active
  int main(int argc, char **argv)
  {
    diagnostic_.add("Joystick Driver Status", this, &Joystick::diagnostics);
    diagnostic_.setHardwareID("none");

    // Parameters
    ros::NodeHandle nh_param("~");
    pub_ = nh_.advertise<sensor_msgs::Joy>("joy", 1);
    nh_param.param<std::string>("dev", joy_dev_, "/dev/input/js0");
    nh_param.param<double>("deadzone", deadzone_, 0.05);
    nh_param.param<double>("autorepeat_rate", autorepeat_rate_, 0);
    nh_param.param<double>("coalesce_interval", coalesce_interval_, 0.001);
    nh_param.param<double>("max_period_with_no_events", max_period_with_no_events_, 0.5);
    
    // Checks on parameters
    if (autorepeat_rate_ > 1 / coalesce_interval_)
      ROS_WARN("joy_node: autorepeat_rate (%f Hz) > 1/coalesce_interval (%f Hz) does not make sense. Timing behavior is not well defined.", autorepeat_rate_, 1/coalesce_interval_);
    
    if (deadzone_ >= 1)
    {
      ROS_WARN("joy_node: deadzone greater than 1 was requested. The semantics of deadzone have changed. It is now related to the range [-1:1] instead of [-32767:32767]. For now I am dividing your deadzone by 32767, but this behavior is deprecated so you need to update your launch file.");
      deadzone_ /= 32767;
    }
    
    if (deadzone_ > 0.9)
    {
      ROS_WARN("joy_node: deadzone (%f) greater than 0.9, setting it to 0.9", deadzone_);
      deadzone_ = 0.9;
    }
    
    if (deadzone_ < 0)
    {
      ROS_WARN("joy_node: deadzone_ (%f) less than 0, setting to 0.", deadzone_);
      deadzone_ = 0;
    }

    if (autorepeat_rate_ < 0)
    {
      ROS_WARN("joy_node: autorepeat_rate (%f) less than 0, setting to 0.", autorepeat_rate_);
      autorepeat_rate_ = 0;
    }
    
    if (coalesce_interval_ < 0)
    {
      ROS_WARN("joy_node: coalesce_interval (%f) less than 0, setting to 0.", coalesce_interval_);
      coalesce_interval_ = 0;
    }

    if ((max_period_with_no_events_ < 0) || (max_period_with_no_events_ > 1.0))
    {
      ROS_WARN("joy_node: max_period_with_no_events (%f) shoul be with [0.0, 1.0], setting to 0.", max_period_with_no_events_);
      max_period_with_no_events_ = 0.0;
    }
    
    // Parameter conversions
    double autorepeat_interval = 1 / autorepeat_rate_;
    double scale = -1. / (1. - deadzone_) / 32767.;
    double unscaled_deadzone = 32767. * deadzone_;

    js_event event;
    struct timeval tv;
    fd_set set;
    int joy_fd;
    event_count_ = 0;
    pub_count_ = 0;
    lastDiagTime_ = ros::Time::now().toSec();

    const ros::Duration max_duration_with_no_events(max_period_with_no_events_);
    ros::Time last_event_time(0.0);
    
    // Big while loop opens, publishes
    while (nh_.ok())
    {                                      
      open_ = false;
      diagnostic_.force_update();
      bool first_fault = true;
      while (true)
      {
        ros::spinOnce();
        if (!nh_.ok())
          goto cleanup;
        joy_fd = open(joy_dev_.c_str(), O_RDONLY);
        if (joy_fd != -1)
        {
          // There seems to be a bug in the driver or something where the
          // initial events that are to define the initial state of the
          // joystick are not the values of the joystick when it was opened
          // but rather the values of the joystick when it was last closed.
          // Opening then closing and opening again is a hack to get more
          // accurate initial state data.
          close(joy_fd);
          joy_fd = open(joy_dev_.c_str(), O_RDONLY);
        }
        if (joy_fd != -1)
          break;
        if (first_fault)
        {
          ROS_ERROR("Couldn't open joystick %s. Will retry every second.", joy_dev_.c_str());
          first_fault = false;
        }
        sleep(1.0);
        diagnostic_.update();
      }
      
      ROS_INFO("Opened joystick: %s. deadzone_: %f.", joy_dev_.c_str(), deadzone_);
      open_ = true;
      diagnostic_.force_update();
      
      bool tv_set = false;
      bool publication_pending = false;
      tv.tv_sec = 1;
      tv.tv_usec = 0;
      sensor_msgs::Joy joy_msg; // Here because we want to reset it on device close.
      while (nh_.ok()) 
      {
        ros::spinOnce();
        
        bool publish_now = false;
        bool publish_soon = false;
        FD_ZERO(&set);
        FD_SET(joy_fd, &set);
        
        //ROS_INFO("Select...");
        int select_out = select(joy_fd+1, &set, NULL, NULL, &tv);
        //ROS_INFO("Tick...");
        if (select_out == -1)
        {
          tv.tv_sec = 0;
          tv.tv_usec = 0;
          //ROS_INFO("Select returned negative. %i", ros::isShuttingDown());
          continue;
          //				break; // Joystick is probably closed. Not sure if this case is useful.
        }
        
        if (FD_ISSET(joy_fd, &set))
        {
          if (read(joy_fd, &event, sizeof(js_event)) == -1 && errno != EAGAIN)
            break; // Joystick is probably closed. Definitely occurs.
          
          //ROS_INFO("Read data...");
          joy_msg.header.stamp = ros::Time().now();
          event_count_++;
          switch(event.type)
          {
          case JS_EVENT_BUTTON:
          case JS_EVENT_BUTTON | JS_EVENT_INIT:
            if(event.number >= joy_msg.buttons.size())
            {
              int old_size = joy_msg.buttons.size();
              joy_msg.buttons.resize(event.number+1);
              for(unsigned int i=old_size;i<joy_msg.buttons.size();i++)
                joy_msg.buttons[i] = 0.0;
            }
            joy_msg.buttons[event.number] = (event.value ? 1 : 0);
            // For initial events, wait a bit before sending to try to catch
            // all the initial events.
            if (!(event.type & JS_EVENT_INIT))
            {
              publish_now = true;
              last_event_time = ros::Time::now();
            }
            else
              publish_soon = true;
            break;
          case JS_EVENT_AXIS:
          case JS_EVENT_AXIS | JS_EVENT_INIT:
            if(event.number >= joy_msg.axes.size())
            {
              int old_size = joy_msg.axes.size();
              joy_msg.axes.resize(event.number+1);
              for(unsigned int i=old_size;i<joy_msg.axes.size();i++)
                joy_msg.axes[i] = 0.0;
            }
            if (!(event.type & JS_EVENT_INIT)) // Init event.value is wrong.
            {
              double val = event.value;
              // Allows deadzone to be "smooth"
              if (val > unscaled_deadzone)
                val -= unscaled_deadzone;
              else if (val < -unscaled_deadzone)
                val += unscaled_deadzone;
              else
                val = 0;
              joy_msg.axes[event.number] = val * scale;
            }
            // Will wait a bit before sending to try to combine events. 				
            publish_soon = true;
            last_event_time = ros::Time::now();
            break;
          default:
            ROS_WARN("joy_node: Unknown event type. Please file a ticket. time=%u, value=%d, type=%Xh, number=%d", event.time, event.value, event.type, event.number);
            break;
          }
        }
        else if (tv_set) // Assume that the timer has expired.
          publish_now = true;
        
        if (publish_now)
        {
          // Assume that all the JS_EVENT_INIT messages have arrived already.
          // This should be the case as the kernel sends them along as soon as
          // the device opens.
          //ROS_INFO("Publish...");
          //pub_.publish(joy_msg);
          publish_now = false;
          tv_set = false;
          publication_pending = false;
          publish_soon = false;
          //pub_count_++;
          if ((ros::Time::now() - last_event_time) < max_duration_with_no_events)
          {
            pub_.publish(joy_msg);
            pub_count_++;
          }
        }
        
        // If an axis event occurred, start a timer to combine with other
        // events.
        if (!publication_pending && publish_soon)
        {
          tv.tv_sec = trunc(coalesce_interval_);
          tv.tv_usec = (coalesce_interval_ - tv.tv_sec) * 1e6;
          publication_pending = true;
          tv_set = true;
          //ROS_INFO("Pub pending...");
        }
        
        // If nothing is going on, start a timer to do autorepeat.
        if (!tv_set && autorepeat_rate_ > 0)
        {
          tv.tv_sec = trunc(autorepeat_interval);
          tv.tv_usec = (autorepeat_interval - tv.tv_sec) * 1e6; 
          tv_set = true;
          //ROS_INFO("Autorepeat pending... %i %i", tv.tv_sec, tv.tv_usec);
        }
        
        if (!tv_set)
        {
          tv.tv_sec = 1;
          tv.tv_usec = 0;
        }
	
        diagnostic_.update();
      } // End of joystick open loop.
      
      close(joy_fd);
      ros::spinOnce();
      if (nh_.ok())
        ROS_ERROR("Connection to joystick device lost unexpectedly. Will reopen.");
    }
    
  cleanup:
    ROS_INFO("joy_node shut down.");
    
    return 0;
  }
// GLIB loop intergration workaround
int Main::EcoreSelectInterceptor(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
#if 0
    // Check each descriptor to see if it is valid
    for (int i = 0; i < nfds; i++)
    {
        if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))
        {
            // Try to get descriptor flags
            int result = fcntl(i, F_GETFL);

            if (result == -1)
            {
                if (errno == EBADF)
                {
                    // This a bad descriptor. Remove all occurrences of it.
                    if (FD_ISSET(i, readfds))
                    {
                        LogPedantic("GLIB_LOOP_INTEGRATION_WORKAROUND: Bad read descriptor: " << i);
                        FD_CLR(i, readfds);
                    }

                    if (FD_ISSET(i, writefds))
                    {
                        LogPedantic("GLIB_LOOP_INTEGRATION_WORKAROUND: Bad write descriptor: " << i);
                        FD_CLR(i, writefds);
                    }

                    if (FD_ISSET(i, exceptfds))
                    {
                        LogPedantic("GLIB_LOOP_INTEGRATION_WORKAROUND: Bad exception descriptor: " << i);
                        FD_CLR(i, exceptfds);
                    }
                }
                else
                {
                    // Unexpected error
                    Assert(0);
                }
            }
        }
    }

    // Find out new maximum
    int newNfds = 0;

    for (int i = 0; i < nfds; i++)
    {
        if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))
            newNfds = i;
    }

    return MainSingleton::Instance().m_oldEcoreSelect(newNfds + 1, readfds, writefds, exceptfds, timeout);

#else

    // We have to check error code here and make another try because of some glib error's.
    fd_set rfds, wfds, efds;
    memcpy(&rfds, readfds, sizeof(fd_set));
    memcpy(&wfds, writefds, sizeof(fd_set));
    memcpy(&efds, exceptfds, sizeof(fd_set));

    int ret = MainSingleton::Instance().m_oldEcoreSelect(nfds, readfds, writefds, exceptfds, timeout);

    if (ret == -1)
    {
        // Check each descriptor to see if it is valid
        for (int i = 0; i < nfds; i++)
        {
            if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))
            {
                // Try to get descriptor flags
                int result = fcntl(i, F_GETFL);

                if (result == -1)
                {
                    if (errno == EBADF)
                    {
                        // This a bad descriptor. Remove all occurrences of it.
                        if (FD_ISSET(i, readfds))
                        {
                            LogPedantic("GLIB_LOOP_INTEGRATION_WORKAROUND: Bad read descriptor: " << i);
                            FD_CLR(i, readfds);
                        }

                        if (FD_ISSET(i, writefds))
                        {
                            LogPedantic("GLIB_LOOP_INTEGRATION_WORKAROUND: Bad write descriptor: " << i);
                            FD_CLR(i, writefds);
                        }

                        if (FD_ISSET(i, exceptfds))
                        {
                            LogPedantic("GLIB_LOOP_INTEGRATION_WORKAROUND: Bad exception descriptor: " << i);
                            FD_CLR(i, exceptfds);
                        }
                    }
                    else
                    {
                        // Unexpected error
                        Assert(0);
                    }
                }
            }
        }

        LogPedantic("GLIB_LOOP_INTEGRATION_WORKAROUND: Bad read descriptor. Retrying with default select.");

        //Retry with old values and return new error
        memcpy(readfds, &rfds, sizeof(fd_set));
        memcpy(writefds, &wfds, sizeof(fd_set));
        memcpy(exceptfds, &efds, sizeof(fd_set));

        // Trying to do it very short
        timeval tm;
        tm.tv_sec = 0;
        tm.tv_usec = 10;

        if (timeout)
            ret = select(nfds, readfds, writefds, exceptfds, &tm);
        else
            ret = select(nfds, readfds, writefds, exceptfds, NULL);
    }

    return ret;
#endif
}
Example #8
0
int main(int argc, char **argv)
{
	int fd = socket(AF_INET, SOCK_STREAM, 0); // TCP

	int on = 1;
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);

	struct sockaddr_in srvaddr;
	bzero(&srvaddr, sizeof srvaddr);
	srvaddr.sin_family = AF_INET;
	srvaddr.sin_addr.s_addr = inet_addr(HOST);
	srvaddr.sin_port = htons(DEFAULT_PORT);

	if(connect(fd, (struct sockaddr *)&srvaddr, sizeof srvaddr) == -1)
	{
		perror("connect() error");
		exit(1);
	}

	struct sockaddr_in myaddr;
	socklen_t len = sizeof myaddr;
	bzero(&myaddr, len);
	getsockname(fd, (struct sockaddr *)&myaddr, &len);
	printf("my port: %hu\n", htons(myaddr.sin_port));


	//pthread_t tid;
	//pthread_create(&tid, NULL, routine, (void *)fd);


	char buf[100];
	
	fd_set rset, wset, eset; // 这些是描述符集合
	struct timeval a;
	a.tv_sec = 0;
	a.tv_usec = 0;
	
	while(1)
	{
#if 0 
		FD_ZERO(&rset); // 添加在这里面的描述符,我们关注他们的“读就绪”状态
		FD_ZERO(&wset); // 添加在这里面的描述符,我们关注他们的“写就绪”状态
		FD_ZERO(&eset); // 添加在这里面的描述符,我们关注他们的“异常就绪”状态
		FD_SET(fd, &rset);
		FD_SET(STDIN_FILENO, &rset); // 将两个描述符添加到rset里面!

		select(fd+1, &rset, &wset, &eset, &a);
		
		bzero(&buf, 100);
		if(FD_ISSET(STDIN_FILENO, &rset)) // 用户输入数据了!
		{
			fgets(buf, 100, stdin);				
			write(fd, buf, strlen(buf));
		}
#endif
		FD_ZERO(&rset); // 添加在这里面的描述符,我们关注他们的“读就绪”状态
		FD_ZERO(&wset); // 添加在这里面的描述符,我们关注他们的“写就绪”状态
		FD_ZERO(&eset); // 添加在这里面的描述符,我们关注他们的“异常就绪”状态
		FD_SET(fd, &rset);
		FD_SET(STDIN_FILENO, &rset); // 将两个描述符添加到rset里面!

		select(fd+1, &rset, &wset, &eset, &a);
		
		char buf[100];
		bzero(buf, 100);
		if(FD_ISSET(fd, &rset)) // 对方有消息来了!
		{
			if(read(fd, buf, 100) == 0)
				break;
			printf("broadcast: %s\n", buf);
		}
		if(FD_ISSET(STDIN_FILENO, &rset)) // 用户输入数据了!
		{
			fgets(buf, 100, stdin);
			write(fd, buf, strlen(buf));
		}
	}

	return 0;
}
Example #9
0
/*
 * Set the date in the machines controlled by timedaemons by communicating the
 * new date to the local timedaemon.  If the timedaemon is in the master state,
 * it performs the correction on all slaves.  If it is in the slave state, it
 * notifies the master that a correction is needed.
 * Returns 0 on success.  Returns > 0 on failure, setting retval to 2;
 */
int
netsettime(time_t tval)
{
	struct timeval tout;
	struct servent *sp;
	struct tsp msg;
	struct sockaddr_in lsin, dest, from;
	fd_set ready;
	long waittime;
	int s, port, timed_ack, found, lerr;
	socklen_t length;
	char hostname[MAXHOSTNAMELEN];

	if ((sp = getservbyname("timed", "udp")) == NULL) {
		warnx("timed/udp: unknown service");
		return (retval = 2);
	}

	dest.sin_port = sp->s_port;
	dest.sin_family = AF_INET;
	dest.sin_addr.s_addr = htonl((u_long)INADDR_ANY);
	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s < 0) {
		if (errno != EPROTONOSUPPORT)
			warn("timed");
		return (retval = 2);
	}

	memset(&lsin, 0, sizeof(lsin));
	lsin.sin_family = AF_INET;
	for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
		lsin.sin_port = htons((u_short)port);
		if (bind(s, (struct sockaddr *)&lsin, sizeof(lsin)) >= 0)
			break;
		if (errno == EADDRINUSE)
			continue;
		if (errno != EADDRNOTAVAIL)
			warn("bind");
		goto bad;
	}
	if (port == IPPORT_RESERVED / 2) {
		warnx("all ports in use");
		goto bad;
	}
	memset(&msg, 0, sizeof(msg));
	msg.tsp_type = TSP_SETDATE;
	msg.tsp_vers = TSPVERSION;
	if (gethostname(hostname, sizeof(hostname))) {
		warn("gethostname");
		goto bad;
	}
	(void)strlcpy(msg.tsp_name, hostname, sizeof(msg.tsp_name));
	msg.tsp_seq = htons((u_short)0);
	msg.tsp_time.tv_sec = htonl((u_long)tval);
	msg.tsp_time.tv_usec = htonl((u_long)0);
	length = sizeof(struct sockaddr_in);
	if (connect(s, (struct sockaddr *)&dest, length) < 0) {
		warn("connect");
		goto bad;
	}
	if (send(s, (char *)&msg, sizeof(struct tsp), 0) < 0) {
		if (errno != ECONNREFUSED)
			warn("send");
		goto bad;
	}

	timed_ack = -1;
	waittime = WAITACK;
loop:
	tout.tv_sec = waittime;
	tout.tv_usec = 0;

	FD_ZERO(&ready);
	FD_SET(s, &ready);
	found = select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout);

	length = sizeof(lerr);
	if (!getsockopt(s,
	    SOL_SOCKET, SO_ERROR, (char *)&lerr, &length) && lerr) {
		if (lerr != ECONNREFUSED)
			warnc(lerr, "send (delayed error)");
		goto bad;
	}

	if (found > 0 && FD_ISSET(s, &ready)) {
		length = sizeof(struct sockaddr_in);
		if (recvfrom(s, &msg, sizeof(struct tsp), 0,
		    (struct sockaddr *)&from, &length) < 0) {
			if (errno != ECONNREFUSED)
				warn("recvfrom");
			goto bad;
		}
		msg.tsp_seq = ntohs(msg.tsp_seq);
		msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec);
		msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec);
		switch (msg.tsp_type) {
		case TSP_ACK:
			timed_ack = TSP_ACK;
			waittime = WAITDATEACK;
			goto loop;
		case TSP_DATEACK:
			(void)close(s);
			return (0);
		default:
			warnx("wrong ack received from timed: %s",
			    tsptype[msg.tsp_type]);
			timed_ack = -1;
			break;
		}
	}
	if (timed_ack == -1)
		warnx("can't reach time daemon, time set locally");

bad:
	(void)close(s);
	return (retval = 2);
}
    void HttpServer::WaitMessage(uint32_t ms)
    {
      fd_set fdsr;
      struct timeval tv;
      int max_sock = m_sock;

      tv.tv_sec = ms / 1000;
      tv.tv_usec = (ms % 1000 ) / 1000;

      FD_ZERO(&fdsr);

#ifdef _WIN32
      /* on Windows, a socket is not an int but a SOCKET (unsigned int) */
      FD_SET((SOCKET)m_sock, &fdsr);
#else
      FD_SET(m_sock, &fdsr);
#endif

      for(std::list<int>::iterator it = m_clients.begin() ; it != m_clients.end() ; ++it)
      {
#ifdef _WIN32
        FD_SET((SOCKET)(*it), &fdsr);
#else
        FD_SET((*it), &fdsr);
#endif

        if((*it) > max_sock)
        {
          max_sock = (*it);
        }
      }

      max_sock++;

      if(select(max_sock, &fdsr, NULL, NULL, ms ? &tv : NULL) > 0)
      {
        if(FD_ISSET(m_sock, &fdsr))
        {
          Accept();
        }

        for(std::list<int>::iterator it = m_clients.begin() ; it != m_clients.end() ; ++it)
        {
          if(FD_ISSET((*it), &fdsr))
          {
            Recv((*it));
          }
        }

        /* remove disconnect socket descriptor */
        for(std::list<int>::iterator it = m_purge.begin() ; it != m_purge.end() ; ++it)
        {
          m_clients.remove((*it));
          m_httpmsgs.erase((*it));
        }

        /* purge disconnected list */
        m_purge.erase(m_purge.begin(), m_purge.end());
      }
      else
      {
        /* error */
      }
    }
Example #11
0
char *Sys_ConsoleInput( void ) {
	// we use this when sending back commands
	static char text[256];
	int i;
	int avail;
	char key;
	field_t *history;

	if ( ttycon && ttycon->value ) {
		avail = read( 0, &key, 1 );
		if ( avail != -1 ) {
			// we have something
			// backspace?
			// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
			if ( ( key == tty_erase ) || ( key == 127 ) || ( key == 8 ) ) {
				if ( tty_con.cursor > 0 ) {
					tty_con.cursor--;
					tty_con.buffer[tty_con.cursor] = '\0';
					tty_Back();
				}
				return NULL;
			}
			// check if this is a control char
			if ( ( key ) && ( key ) < ' ' ) {
				if ( key == '\n' ) {
					// push it in history
					Hist_Add( &tty_con );
					strcpy( text, tty_con.buffer );
					Field_Clear( &tty_con );
					key = '\n';
					write( 1, &key, 1 );
					return text;
				}
				if ( key == '\t' ) {
					tty_Hide();
					Field_CompleteCommand( &tty_con );
					// Field_CompleteCommand does weird things to the string, do a cleanup
					//   it adds a '\' at the beginning of the string
					//   cursor doesn't reflect actual length of the string that's sent back
					tty_con.cursor = strlen( tty_con.buffer );
					if ( tty_con.cursor > 0 ) {
						if ( tty_con.buffer[0] == '\\' ) {
							for ( i = 0; i <= tty_con.cursor; i++ )
							{
								tty_con.buffer[i] = tty_con.buffer[i + 1];
							}
							tty_con.cursor--;
						}
					}
					tty_Show();
					return NULL;
				}
				avail = read( 0, &key, 1 );
				if ( avail != -1 ) {
					// VT 100 keys
					if ( key == '[' || key == 'O' ) {
						avail = read( 0, &key, 1 );
						if ( avail != -1 ) {
							switch ( key )
							{
							case 'A':
								history = Hist_Prev();
								if ( history ) {
									tty_Hide();
									tty_con = *history;
									tty_Show();
								}
								tty_FlushIn();
								return NULL;
								break;
							case 'B':
								history = Hist_Next();
								tty_Hide();
								if ( history ) {
									tty_con = *history;
								} else
								{
									Field_Clear( &tty_con );
								}
								tty_Show();
								tty_FlushIn();
								return NULL;
								break;
							case 'C':
								return NULL;
							case 'D':
								return NULL;
							}
						}
					}
				}
				Com_DPrintf( "droping ISCTL sequence: %d, tty_erase: %d\n", key, tty_erase );
				tty_FlushIn();
				return NULL;
			}
			// push regular character
			tty_con.buffer[tty_con.cursor] = key;
			tty_con.cursor++;
			// print the current line (this is differential)
			write( 1, &key, 1 );
		}
		return NULL;
	} else
	{
		int len;
		fd_set fdset;
		struct timeval timeout;

		if ( !com_dedicated || !com_dedicated->value ) {
			return NULL;
		}

		if ( !stdin_active ) {
			return NULL;
		}

		FD_ZERO( &fdset );
		FD_SET( 0, &fdset ); // stdin
		timeout.tv_sec = 0;
		timeout.tv_usec = 0;
		if ( select( 1, &fdset, NULL, NULL, &timeout ) == -1 || !FD_ISSET( 0, &fdset ) ) {
			return NULL;
		}

		len = read( 0, text, sizeof( text ) );
		if ( len == 0 ) { // eof!
			stdin_active = qfalse;
			return NULL;
		}

		if ( len < 1 ) {
			return NULL;
		}
		text[len - 1] = 0; // rip off the /n and terminate

		return text;
	}
}
Example #12
0
void gwrl_bkd_gather(gwrl * rl) {
	int res = 0;
	gwrlevt_flags_t newflags = 0;
	fd_set fds[3];
	gwrlsrc * src = NULL;
	gwrlsrc_file * fsrc = NULL;
	gwrlevt * evt = NULL;
	gwrlbkd * bkd = rl->backend;
	gwrlbkd_select * sbkd = _gwrlbkds(bkd);
	
	//setup timeout for select
	struct timeval timeout;
	struct timeval * timeoutp = &timeout;
	if(bkd->timeout.tv_sec == sec_min && bkd->timeout.tv_nsec == nsec_min) {
		timeoutp = NULL;
	} else {
		gwtm_timespec_to_timeval(&bkd->timeout,&timeout);
	}
	
	//if sleep isn't allowed set timeout to 0
	if(!timeoutp && flisset(rl->flags,GWRL_NOSLEEP)) {
		timeoutp = &timeout;
		timeout.tv_sec = 0;
		timeout.tv_usec = 0;

		#ifdef GWRL_COVERAGE_INTERNAL_ASSERT_VARS
			if(asserts_var1 == gwrlbkd_no_sleep_assert_true) {
				asserts_var2 = true;
			}
		#endif
	}
	
	//initialize fds
	FD_ZERO(&(fds[0]));
	FD_ZERO(&(fds[1]));
	FD_ZERO(&(fds[2]));
	
	//reset fds
	memcpy(&(fds[0]),&(sbkd->src[0]),sizeof(fd_set));
	memcpy(&(fds[1]),&(sbkd->src[1]),sizeof(fd_set));
	memcpy(&(fds[2]),&(sbkd->src[2]),sizeof(fd_set));
	
	//call select, wrapped in sleeping flags so other threads can wake us
	flset(rl->flags,GWRL_SLEEPING);
	res = select(sbkd->maxfd+1,&(fds[0]),&(fds[1]),&(fds[2]),timeoutp);
	flclr(rl->flags,GWRL_SLEEPING);
	
	if(res == 0) return; //timeout
	
	//break and let the event loop continue or start over.
	//if a signal did happen, the event loop may have an
	//event that needs processing.
	if(res < 0 && (errno == EINTR || errno == EAGAIN)) return;
	
	//bad fd, unforunately select doesn't tell us which
	//one it was so we have to search for it.
	if(res < 0 && errno == EBADF) {
		gwrl_src_file_find_badfd_post_evt(rl);
		return;
	}
	
	//invalid timeout or invalid number of fds.
	if(res < 0 && errno == EINVAL) {
		//invalid timeout, break and let process events recalculate timeouts.
		if(timeout.tv_sec < 0 || timeout.tv_usec < 0) return;
		
		//nfds parameter to select() is too large, not sure how to handle
		fprintf(stderr,"select: file descriptor limit reached. exiting. \n");
		exit(1);
	}
	
	//valid events are ready
	if(res > 0) {
		fsrc = _gwrlsrcf(rl->sources[GWRL_SRC_TYPE_FILE]);
		while(fsrc) {
			src = _gwrlsrc(fsrc);
			newflags = 0;
			
			if(!flisset(src->flags,GWRL_ENABLED)) {
				fsrc = _gwrlsrcf(src->next);
				continue;
			}
			
			if(FD_ISSET(fsrc->fd,&fds[0])) flset(newflags,GWRL_RD);
			if(FD_ISSET(fsrc->fd,&fds[1])) flset(newflags,GWRL_WR);
			if(FD_ISSET(fsrc->fd,&fds[2])) flset(newflags,GWRL_RD);
			
			if(newflags > 0) {
				evt = gwrl_evt_createp(rl,src,src->callback,src->userdata,fsrc->fd,newflags);
				gwrl_post_evt(rl,evt);
			}
			
			fsrc = _gwrlsrcf(src->next);
		}
	}
}
Example #13
0
wi_socket_t * wi_socket_wait_multiple(wi_array_t *array, wi_time_interval_t timeout) {
	wi_enumerator_t		*enumerator;
	wi_socket_t			*socket, *waiting_socket = NULL;
	struct timeval		tv;
	fd_set				rfds, wfds;
	int					state, max_sd;

	tv = wi_dtotv(timeout);
	max_sd = -1;

	FD_ZERO(&rfds);
	FD_ZERO(&wfds);

	wi_array_rdlock(array);
	
	enumerator = wi_array_data_enumerator(array);
	
	while((socket = wi_enumerator_next_data(enumerator))) {
		if(wi_string_length(socket->buffer) > 0) {
			waiting_socket = socket;
			
			break;
		}
		
		if(socket->direction & WI_SOCKET_READ)
			FD_SET(socket->sd, &rfds);

		if(socket->direction & WI_SOCKET_WRITE)
			FD_SET(socket->sd, &wfds);

		if(socket->sd > max_sd)
			max_sd = socket->sd;
	}

	wi_array_unlock(array);
	
	if(waiting_socket)
		return waiting_socket;
	
	state = select(max_sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
	
	if(state < 0) {
		wi_error_set_errno(errno);

		return NULL;
	}
	
	wi_array_rdlock(array);

	enumerator = wi_array_data_enumerator(array);
	
	while((socket = wi_enumerator_next_data(enumerator))) {
		if(FD_ISSET(socket->sd, &rfds) || FD_ISSET(socket->sd, &wfds)) {
			waiting_socket = socket;

			break;
		}
	}
	
	wi_array_unlock(array);
	
	return waiting_socket;
}
Example #14
0
void ident_check(struct descriptor_data *d, int pulse)
{
  fd_set fd, efd;
  int rc, rmt_port, our_port, len;
  char user[256], *p;

  extern struct timeval null_time;
  extern int port;

  /*
   * Each pulse, this checks if the ident is ready to proceed to the
   * next state, by calling select to see if the socket is writeable
   * (connected) or readable (response waiting).  
   */

  switch (STATE(d)) {
    case CON_IDCONING:
      /* waiting for connect() to finish */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, (fd_set *) 0, &fd, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (conning)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        /* exception, such as failure to connect */
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDCONED;
      break;

    case CON_IDCONED:
      /* connected, write request */

      sprintf(buf, "%d, %d\n\r", ntohs(d->peer_port), port);

      len = strlen(buf);
#ifdef CIRCLE_WINDOWS
      if (send(d->ident_sock, buf, len, 0) < 0) {
#else
      if (write(d->ident_sock, buf, len) != len) {
        if (errno != EPIPE) /* read end closed (no remote identd) */
#endif
          logerror("ident check write (conned)");

        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREADING;
      break;

    case CON_IDREADING:
      /* waiting to read */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, &fd, (fd_set *) 0, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (reading)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREAD;
      break;

    case CON_IDREAD:
      /* read ready, get the info */

#ifdef CIRCLE_WINDOWS
      if ((len = recv(d->ident_sock, buf, sizeof(buf) - 1, 0)) < 0)
#else
      if ((len = read(d->ident_sock, buf, sizeof(buf) - 1)) < 0)
#endif
        logerror("ident check read (read)");

      else {
        buf[len] = '\0';
        if (sscanf(buf, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, user) != 3) {

          /* check if error or malformed */
          if (sscanf(buf, "%u , %u : ERROR : %255s", &rmt_port, &our_port, user) == 3) {
            sprintf(buf2, "Ident error from %s: \"%s\"", d->hostIP, user);
            stderr_log(buf2);
          } else {
            /* strip off trailing newline */
            for (p = buf + len - 1; p > buf && ISNEWL(*p); p--)
              ;
            p[1] = '\0';

            sprintf(buf2, "Malformed ident response from %s: \"%s\"", d->hostIP, buf);
            stderr_log(buf2);
          }
        } else {

          len = HOST_LENGTH - strlen(d->hostIP);

          if (len > 0) {
            strncpy(buf2, user, len - 1);
            buf2[len - 1] = '\0';
            strcpy(d->username, buf2);
          }

          /* if len <= 0, no space for username */
        }
      }

      STATE(d) = CON_ASKNAME;
      break;

    case CON_ASKNAME:
      /* ident complete, ask for name */

      /* close up the ident socket, if one is opened. */
      if (d->ident_sock != INVALID_SOCKET) {
        close(d->ident_sock);
        d->ident_sock = INVALID_SOCKET;
      }
      d->idle_tics = 0;

      /* extra ban check */
      if ((d->host[0] != '\0' && isbanned(d->host) == BAN_ALL) || isbanned(d->hostIP)) {
        if (d->host[0] != '\0') {
          sprintf(buf, "Connection attempt denied from [%s]", d->host);
        } else {
          sprintf(buf, "Connection attempt denied from [%s]", d->hostIP);
        }
        mudlog(buf, 'S', COM_IMMORT, TRUE);
        close_socket(d);
        return;
      }

      /* SEND_TO_Q("\x1B[2K\n\rBy what name do you wish to be known? ", d); */
      STATE(d) = CON_GET_TERMTYPE;
      return;

    default:
      return;
  }

  /*
   * Print a dot every second so the user knows he hasn't been forgotten.
   * Allow the user to go on anyways after waiting IDENT_TIMEOUT seconds.
   */
  if ((pulse % PASSES_PER_SEC) == 0) {
    SEND_TO_Q(".", d);

    if (d->idle_tics++ >= IDENT_TIMEOUT)
      STATE(d) = CON_ASKNAME;
  }
}

/* returns 1 if waiting for ident to complete, else 0 */
int waiting_for_ident(struct descriptor_data *d)
{
  switch (STATE(d)) {
    case CON_IDCONING:
    case CON_IDCONED:
    case CON_IDREADING:
    case CON_IDREAD:
    case CON_ASKNAME:
      return 1;
  }
  return 0;
}
Example #15
0
int main(int argc, char *argv[])
{
	pid_t child_pid;
	int child_exit_status;
	struct termios tty_attr;
	struct winsize window_size;
	int pty_master;

	/* for select */
	fd_set readfds;
	fd_set writefds;

	unsigned err_n_rpty = 0;
	unsigned err_n_wpty = 0;
	unsigned err_n_stdin = 0;
	unsigned err_n_stdout = 0;

	int done = 0;

	/* the ring buffers */
	char inbuf_mem[BUFSIZE];
	char outbuf_mem[BUFSIZE];
	struct ring_buffer inbuf;
	struct ring_buffer outbuf;
	rb_init(&inbuf, inbuf_mem, sizeof(inbuf_mem));
	rb_init(&outbuf, outbuf_mem, sizeof(outbuf_mem));

	if (argc == 1) {
		printf("usage: %s PROGRAM [ARGS]...\n", argv[0]);
		exit(1);
	}

	/* We need I/O calls to fail with EINTR on SIGCHLD... */
	if (signal(SIGCHLD, sigchld_handler) == SIG_ERR) {
		perror("signal(SIGCHLD,...)");
		exit(EX_OSERR);
	}

	if (isatty(STDIN_FILENO)) {
		/* get terminal parameters associated with stdout */
		if (tcgetattr(STDOUT_FILENO, &tty_attr) < 0) {
			perror("tcgetattr(stdout,...)");
			exit(EX_OSERR);
		}

		/* get window size */
		if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &window_size) < 0) {
			perror("ioctl(stdout,...)");
			exit(1);
		}

		child_pid = forkpty(&pty_master, NULL, &tty_attr, &window_size);
	} else { /* not interactive */
		child_pid = forkpty(&pty_master, NULL, NULL, NULL);
	}

	if (child_pid < 0) {
		perror("forkpty()");
		exit(EX_OSERR);
	}
	if (child_pid == 0) { /* in the child */
		struct termios s_tty_attr;
		if (tcgetattr(STDIN_FILENO, &s_tty_attr)) {
			perror("tcgetattr(stdin,...)");
			exit(EXIT_FAILURE);
		}
		/* Turn off echo */
		s_tty_attr.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
		/* Also turn of NL to CR?LF on output */
		s_tty_attr.c_oflag &= ~(ONLCR);
		if (tcsetattr(STDIN_FILENO, TCSANOW, &s_tty_attr)) {
			perror("tcsetattr(stdin,...)");
			exit(EXIT_FAILURE);
		}

		if (execvp(argv[1], argv + 1)) {
			perror("execvp()");
			exit(EXIT_FAILURE);
		}
	}

	/* Non blocking mode for all file descriptors. */
	setfd_nonblock(pty_master);
	setfd_nonblock(STDIN_FILENO);
	setfd_nonblock(STDOUT_FILENO);

	if (isatty(STDIN_FILENO)) {
		if (tty_semi_raw(STDIN_FILENO) < 0) {
			perror("tty_semi_raw(stdin)");
		}
		if (atexit(tty_atexit) < 0) {
			perror("atexit()");
		}
	}

	do {
		/* Accept events only on fds, that we can handle now. */
		int do_select = 0;
		FD_ZERO(&readfds);
		FD_ZERO(&writefds);

		if (rb_space(&outbuf) > 0 && err_n_rpty < MAXRETR) {
			FD_SET(pty_master, &readfds);
			do_select = 1;
		}

		if (!rb_isempty(&inbuf) && err_n_wpty < MAXRETR) {
			FD_SET(pty_master, &writefds);
			do_select = 1;
		}

		if (rb_space(&inbuf) > 0 && err_n_stdin < MAXRETR) {
			FD_SET(STDIN_FILENO, &readfds);
			do_select = 1;
		}

		if (!rb_isempty(&outbuf) && err_n_stdout < MAXRETR) {
			FD_SET(STDOUT_FILENO, &writefds);
			do_select = 1;
		}

		if (!do_select) {
#ifdef DEBUG
			fprintf(stderr, "No I/O job for us, calling waitpid()...\n");
#endif
			while (waitpid(child_pid, &child_exit_status, 0) < 0)
			{
				/* nothing */
			}
			break;
		}

		int select_rc = select(pty_master + 1, &readfds, &writefds, NULL, NULL);
		if (select_rc < 0) {
			perror("select()");
			exit(EX_IOERR);
		}
#ifdef DEBUG
		fprintf(stderr, "select() returned %d\n", select_rc);
#endif

		if (FD_ISSET(STDOUT_FILENO, &writefds)) {
#ifdef DEBUG
			fprintf(stderr, "stdout can be written\n");
#endif
			ssize_t n = rb_write(&outbuf, STDOUT_FILENO);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_stdout++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes written into stdout\n", n);
			else
				perror("write(stdout,...)");
#endif
		}

		if (FD_ISSET(pty_master, &writefds)) {
#ifdef DEBUG
			fprintf(stderr, "pty_master can be written\n");
#endif
			ssize_t n = rb_write(&inbuf, pty_master);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_wpty++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes written into pty_master\n", n);
			else
				perror("write(pty_master,...)");
#endif
		}

		if (FD_ISSET(STDIN_FILENO, &readfds)) {
#ifdef DEBUG
			fprintf(stderr, "stdin can be read\n");
#endif
			ssize_t n = rb_read(&inbuf, STDIN_FILENO);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_stdin++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes read from stdin\n", n);
			else
				perror("read(stdin,...)");
#endif
		}

		if (FD_ISSET(pty_master, &readfds)) {
#ifdef DEBUG
			fprintf(stderr, "pty_master can be read\n");
#endif
			ssize_t n = rb_read(&outbuf, pty_master);
			if (n <= 0 && n != EINTR && n != EAGAIN)
				err_n_rpty++;
#ifdef DEBUG
			if (n >= 0)
				fprintf(stderr, "%d bytes read from pty_master\n", n);
			else
				perror("read(pty_master,...)");
#endif
		}

		if (!done && waitpid(child_pid, &child_exit_status, WNOHANG) > 0)
			done = 1;

	} while (!done
		|| !(rb_isempty(&inbuf) || err_n_wpty >= MAXRETR)
		|| !(rb_isempty(&outbuf) || err_n_stdout >= MAXRETR));

#ifdef DEBUG
	fprintf(stderr, "inbuf: %u bytes left, outbuf: %u bytes left\n", inbuf.count, outbuf.count);
	fprintf(stderr, "err_n_rpty=%u, err_n_wpty=%u, err_n_stdin=%u, err_n_stdout=%u\n",
		err_n_rpty, err_n_wpty, err_n_stdin, err_n_stdout);
#endif

	if (WIFEXITED(child_exit_status))
		exit(WEXITSTATUS(child_exit_status));
	else if (WIFSIGNALED(child_exit_status))
		exit(128 + WTERMSIG(child_exit_status));

	exit(EXIT_FAILURE);
}
/*
 ============================================================================
 Funcion principal
 ============================================================================
 */
int main(int argc, char *argv[]) {
	stHeaderIPC *unHeaderIPC = NULL, *stHeaderSwitch = NULL;
	stMensajeIPC unMensaje;
	stPCB *unPCB = NULL;
	t_UMCConfig UMCConfig;
	pthread_t p_thread, p_threadCpu;
	char* temp_file = "nucleo.log";
	elEstadoActual.path_conf = argv[1];
	uint32_t pid_desconectado = 0;
	int unCliente = 0, maximoAnterior = 0, unSocket, agregarSock;
	struct sockaddr addressAceptado;

	/*Inicializacion de las colas del planificador*/
	inicializar_pidCounter();
	inicializar_cola_ready();
	listaBlock = list_create();
	consola_crear_lista();

	log_create(temp_file, "NUCLEO", -1, LOG_LEVEL_INFO);

	log_info("Arrancando el Nucleo");

	if (elEstadoActual.path_conf == NULL) {
		log_error("Falta el parametro de configuracion");
		exit(-1);
	}

	/*Carga del archivo de configuracion*/
	if (loadInfo(&elEstadoActual, 0)) {
		log_error("Error al cargar la configuracion");
		exit(-2);
	}
	log_info("Configuracion cargada satisfactoriamente...");

	/*Se lanza el thread para identificar cambios en el archivo de configuracion*/
	pthread_create(&p_thread, NULL, &monitor_configuracion, (void*) &elEstadoActual);

	inicializarThreadsDispositivos(&elEstadoActual);

	/*Inicializacion de listas de socket*/
	FD_ZERO(&(fds_master));
	FD_ZERO(&(read_fds));

	/*Inicializacion de socket de escucha*/
	elEstadoActual.salir = 0;
	elEstadoActual.sockEscuchador = -1;

	/*Iniciando escucha en el socket escuchador de Consola*/
	elEstadoActual.sockEscuchador = escuchar(elEstadoActual.miPuerto);
	FD_SET(elEstadoActual.sockEscuchador, &(fds_master));
	log_debug("Se establecio conexion con el socket de escucha...");

	/*Seteamos el maximo socket*/
	elEstadoActual.fdMax = elEstadoActual.sockEscuchador;

	/*Conexion con el proceso UMC*/
	log_debug("Estableciendo conexion con la UMC...");
	elEstadoActual.sockUmc = conectar(elEstadoActual.ipUmc, elEstadoActual.puertoUmc);

	if (elEstadoActual.sockUmc != -1) {
		//FD_SET(elEstadoActual.sockUmc, &(fds_master));

		unHeaderIPC = nuevoHeaderIPC(ERROR);
		if (!recibirHeaderIPC(elEstadoActual.sockUmc, unHeaderIPC)) {
			log_error("UMC handshake error - No se pudo recibir mensaje de respuesta");
			log_error("No se pudo conectar a la UMC");
			elEstadoActual.salir = 1;
		}
		if (unHeaderIPC->tipo == QUIENSOS) {
			unHeaderIPC = nuevoHeaderIPC(CONNECTNUCLEO);
			if (!enviarHeaderIPC(elEstadoActual.sockUmc, unHeaderIPC)) {
				log_error("UMC handshake error - No se pudo enviar mensaje de conexion");
				log_error("No se pudo conectar a la UMC");
				elEstadoActual.salir = 1;
			}
		}
		liberarHeaderIPC(unHeaderIPC);
		unHeaderIPC = nuevoHeaderIPC(OK);
		if (!recibirHeaderIPC(elEstadoActual.sockUmc, unHeaderIPC)) {
			log_error("UMC handshake error - No se pudo recibir mensaje de confirmacion");
			log_error("No se pudo conectar a la UMC");
			elEstadoActual.salir = 1;
		} else {
			if (recibirConfigUMC(elEstadoActual.sockUmc, &UMCConfig)) {
				log_error("UMC error - No se pudo recibir la configuracion");
				close(unCliente);
				exit(-2);
			}
			agregar_master(elEstadoActual.sockUmc,maximoAnterior);
			log_info("Paginas por proceso:[%d]", UMCConfig.paginasXProceso);
			log_info("Tamanio de pagina:[%d]", UMCConfig.tamanioPagina);

			elEstadoActual.tamanio_paginas = UMCConfig.tamanioPagina;
		}
		liberarHeaderIPC(unHeaderIPC);
	} else {
		log_error("No se pudo conectar a la UMC");
		elEstadoActual.salir = 1;
	}

	/*Ciclo Principal del Nucleo*/
	log_info(".............................................................................");
	log_info("..............................Esperando Conexion.............................\n\n");
	fflush(stdout);

	while (elEstadoActual.salir == 0) {
		read_fds = fds_master;

		if (seleccionar(elEstadoActual.fdMax, &read_fds, 0) == -1) {
			log_error("Error Preparando el Select");
			break;
		}

		for (unSocket = 0; unSocket <= elEstadoActual.fdMax; unSocket++) {

			if (FD_ISSET(unSocket, &read_fds)) {
				/*Nueva conexion*/
				if (unSocket == elEstadoActual.sockEscuchador) {
					unCliente = aceptar(elEstadoActual.sockEscuchador, &addressAceptado);
					unHeaderIPC = nuevoHeaderIPC(QUIENSOS);
					if (!enviarHeaderIPC(unCliente, unHeaderIPC)) {
						log_error("Cliente Handshake error - No se puede enviar el mensaje QUIENSOS");
						liberarHeaderIPC(unHeaderIPC);
						close(unCliente);
						break;/*Sale del for*/
					}
					liberarHeaderIPC(unHeaderIPC);
					unHeaderIPC = nuevoHeaderIPC(ERROR);
					if (!recibirHeaderIPC(unCliente, unHeaderIPC)) {
						log_error("Cliente Handshake error - No se puede recibir el mensaje");
						liberarHeaderIPC(unHeaderIPC);
						close(unCliente);
						break;/*Sale del for*/
					}

					/*Identifico quien se conecto y procedo*/
					switch (unHeaderIPC->tipo) {
					case CONNECTCONSOLA:
						stHeaderSwitch = nuevoHeaderIPC(OK);
						if (!enviarHeaderIPC(unCliente, stHeaderSwitch)) {
							log_error("Handshake Consola - No se pudo enviar el OK");
							liberarHeaderIPC(stHeaderSwitch);
							close(unCliente);
							break;/*Sale del switch*/
						}
						liberarHeaderIPC(stHeaderSwitch);
						log_info("Nueva consola conectada");
						agregarSock = 1;
						/*Agrego el socket conectado a la lista Master*/
						if (agregarSock == 1) {
							agregar_master(unCliente, maximoAnterior);
							agregarSock = 0;
						}
						/* Recibo Programa */
						if (!recibirMensajeIPC(unCliente, &unMensaje)) {
							log_error("No se puede recibir el programa a procesar");
							break;/*Sale del switch*/
						} else {
							if (unMensaje.header.tipo == SENDANSISOP) {
								/*metadata_desde_literal hace un malloc adentro*/
								int cantidadDePaginasCodigo = calcular_cantidad_paginas(unMensaje.header.largo, UMCConfig.tamanioPagina);
								/***Creacion del PCB***/
								unPCB = crear_pcb(unCliente, cantidadDePaginasCodigo, elEstadoActual.stackSize, &unMensaje);
								if (unPCB == NULL) {
									log_error("Error al crear el PCB... se cierra la consola\n");
									quitar_master(unCliente, maximoAnterior);
									close(unCliente);
									break;/*Sale del switch*/
								}
								if (inicializar_programa(unPCB, (char *)unMensaje.contenido, elEstadoActual.sockUmc) == EXIT_FAILURE) {
									log_error("No se pudo inicializar el programa");
									quitar_master(unCliente, maximoAnterior);
									close(unCliente);
									break;/*Sale del switch*/
								}

								/* Inicializada la consola la agrego a consolas activas */
								agregar_consola(unCliente, unPCB->pid);

								/*Cuando se usa mensajeIPC liberar el contenido*/
								free(unMensaje.contenido);
								ready_productor(unPCB);
								log_info("PCB [PID - %d] NEW a READY\n", unPCB->pid);
								fflush(stdout);
							}

						}
						break;

					case CONNECTCPU:
						stHeaderSwitch = nuevoHeaderIPC(OK);
						if (!enviarHeaderIPC(unCliente, stHeaderSwitch)) {
							liberarHeaderIPC(stHeaderSwitch);
							log_error("CPU error - No se pudo enviar OK");
							close(unCliente);
							break;/*Sale del switch*/
						}
						liberarHeaderIPC(stHeaderSwitch);
						if (pthread_create(&p_threadCpu, NULL, (void*) consumidor_cpu, (void*) &unCliente) != 0) {
							log_error("No se pudo lanzar el hilo correspondiente al cpu conectado");
							close(unCliente);
							break;/*Sale del switch*/
						}
						log_info("Se lanza hilo de atencion a CPU conectado");
						fflush(stdout);
						break;
					default:
						break;
					}
					if (unHeaderIPC != NULL) {
						liberarHeaderIPC(unHeaderIPC);
					}
				} else {
					/*Conexion existente*/
					log_debug("Recibi otro evento de un cliente ya conectado");
					if (!recibirMensajeIPC(unSocket, &unMensaje)) {
						log_info("Desconexion detectada");

						// Desconexion de una consola
   						pid_desconectado = borrar_consola(unSocket);

						// Desconexion de la UMC
						if (unSocket == elEstadoActual.sockUmc) {
							log_info("Se perdio conexion con la UMC...");
							elEstadoActual.salir = 1;
							cerrarSockets(&elEstadoActual);
						}

						if (unSocket == elEstadoActual.sockEscuchador) {
							log_debug("Se perdio conexion...");
						}
						/*Saco el socket de la lista Master*/
						quitar_master(unSocket, maximoAnterior);
						fflush(stdout);
					}
				}

			}

		}
	}
	destruir_planificador();
	destruir_lista_dispositivos(&elEstadoActual);
	consola_destruir_lista(&elEstadoActual);
	cerrarSockets(&elEstadoActual);
	finalizarSistema(&unMensaje, unSocket, &elEstadoActual);
	log_info("Fin del programa");
	return 0;
}
Example #17
0
int main(int argc, char** argv)
{
  ipcio_t data_block = IPCIO_INIT;
  key_t key = DADA_DEFAULT_BLOCK_KEY;
  int status = 0;

  char eventfile[128];
  FILE *infd, *evfd;

  //get this many bytes at a time from data socket
  int BUFSIZE = UDP_HDR_SIZE + VDIF_PKT_SIZE; 
  char buf[BUFSIZE];
  char dev[16] = ETHDEV;
  char hostname[MAXHOSTNAME];
  gethostname(hostname,MAXHOSTNAME);
  char *starthost = strstr(hostname, "difx");
  
  int nbytes = 0, state = STATE_STOPPED;
  uint64_t port = WRITER_SERVICE_PORT;
  //int cmd = CMD_NONE;
  char cmd = CMD_NONE;
  int ii, arg, maxsock = 0; 
  
  fd_set readfds;
  struct timeval tv; //timeout for select()--set it to zero 
  tv.tv_sec = 0;
  tv.tv_usec = 0;

  Connection c;
  c.sockoptval = 1; //release port immediately after closing connection

  Connection raw;
  raw.alen = sizeof(raw.rem_addr);
  raw.sockoptval = 32*1024*1024; //size of data socket internal buffer

  // For gathering stats on frame skips
  long framenumtmp, framenum[2], framediff;
  framenum[0] = -1;
  framenum[1] = -1;
  int threadid = -1; 
  FILE* skiplogfd;
  char skiplogfile[128];
  time_t currt;
  char currt_string[128];
  struct tm *tmpt;

  while ((arg = getopt(argc, argv, "hk:p:e:")) != -1) {
    switch(arg) {

    case 'h':
      usage ();
      return 0;
      
    case 'k':
      if (sscanf (optarg, "%x", &key) != 1) {
	fprintf (stderr, "writer: could not parse key from %s\n", optarg);
	return -1;
      }
      break;
      
    case 'p':
      if (sscanf (optarg, "%"PRIu64"", &port) != 1) {
	fprintf (stderr, "writer: could not parse port from %s\n", optarg);
	return -1;
      }
      break;
    
    case 'e':
      if (sscanf (optarg, "%s", dev) != 1) {
	fprintf (stderr, "writer: could not parse ethernet device from %s\n", optarg);
	return -1;
      }
      break;
      
    }
  }

  sprintf(skiplogfile,"%s%s%s%s","skiplog-",starthost,dev,".txt");
  if((skiplogfd = fopen(skiplogfile, "w")) == NULL) {
    fprintf(stderr,"Writer: Could not open skiplog file %s for writing.\n",skiplogfile);
    exit(1);
  }
  
  //Try to connect to existing data block
  if(ipcio_connect(&data_block,key) < 0)
    exit(1);
  fprintf(stderr,"after ipcio_connect\n");

  //create listening socket 
  if(serve(port, &c) < 0) {
    fprintf(stderr,"Writer: Failed to create listening socket.\n");
    exit(1);
  }
  maxsock = c.rqst;

  //Open raw data stream socket
  raw.svc = openRawSocket(dev,0);
  if(raw.svc < 0) {
    fprintf(stderr, "Cannot open raw socket on %s. Error code %d\n", dev, raw.svc);
    exit(1);
  }
  setsockopt(raw.svc, SOL_SOCKET, SO_RCVBUF, (char *)&(raw.sockoptval), sizeof(raw.sockoptval));
  if(raw.svc > maxsock)
    maxsock = raw.svc;

  //ii = 0;

  while(1) {
    //ii++;
    //printf("ii: %d state: %d cmd: %d\n",ii,state,cmd);

    if(state == STATE_STOPPED) {
      if(cmd == CMD_NONE)
	cmd = wait_for_cmd(&c);

      if(cmd == CMD_START) {
	state = STATE_STARTED;
	if(ipcio_open(&data_block,'W') < 0)
	  exit(1);
	fprintf(stderr,"after ipcio_open, W\n");
	cmd = CMD_NONE;
      }
      else if(cmd == CMD_EVENT) {
	fprintf(stderr, "Writer: ignored CMD_EVENT in STATE_STOPPED.\n");
	cmd = CMD_NONE;
      }
      else if(cmd == CMD_STOP) {
	fprintf(stderr, "Writer: ignored CMD_STOP in STATE_STOPPED.\n");
	cmd = CMD_NONE;
      }
      else if(cmd == CMD_QUIT) {
	shutdown(c.rqst,2);
	return 0;
      }
    }
    
    //if state is STARTED, poll the command listening socket and the VDIF raw data socket
    if(state == STATE_STARTED) {
      FD_ZERO(&readfds);
      FD_SET(c.rqst, &readfds);
      FD_SET(raw.svc, &readfds);
      select(maxsock+1,&readfds,NULL,NULL,&tv);
      
      //if input is waiting on listening socket, read it
      if(FD_ISSET(c.rqst,&readfds)) {
	cmd = wait_for_cmd(&c);
      }

      if(cmd == CMD_EVENT) {
	//close data block
	if(ipcio_close(&data_block) < 0)
	  exit(1);
	fprintf(stderr,"after ipcio_close\n");
	
	//dump DB to file
	currt = time(NULL);
	tmpt = localtime(&currt);
	strftime(currt_string,sizeof(currt_string), "%Y%m%d_%H%M%S", tmpt);
	*(currt_string+15) = 0;
	sprintf(eventfile,"%s/%s%s_%s_ev.out",EVENTDIR,starthost,dev,currt_string);
	
	if((evfd = fopen(eventfile,"w")) == NULL) {
	  fprintf(stderr,"Writer: Could not open file %s for writing.\n",eventfile);
	}
	else {
	  event_to_file(&data_block,evfd);
	  fclose(evfd);
	}

	//Get pending commands, resume writing to ring buffer if there are none
	FD_ZERO(&readfds);
	FD_SET(c.rqst, &readfds);
	FD_SET(raw.svc, &readfds);
	select(maxsock+1,&readfds,NULL,NULL,&tv);

	state = STATE_STOPPED;
	if(FD_ISSET(c.rqst,&readfds)) {
	  cmd = wait_for_cmd(&c);
	  fprintf(stderr,"Writer: flushed out command socket after event_to_file.\n");
	}
	else
	  cmd = CMD_START; 
	
	continue; 
      }
      //if command is stop, change state to STOPPED, close data block
      else if(cmd == CMD_STOP) {
	state = STATE_STOPPED;
	if(ipcio_close(&data_block) < 0)
	  exit(1);
	fprintf(stderr,"after ipcio_close\n");
	cmd = CMD_NONE;
	continue;
      }
      //if command is quit, close data block, shutdown listening socket, return
      else if(cmd == CMD_QUIT) {
	if(ipcio_close(&data_block) < 0)
	  exit(1);
	fprintf(stderr,"after ipcio_close\n");
	shutdown(c.rqst,2);
	return 0;
      }
      else if(cmd == CMD_START) {
	fprintf(stderr,"Writer: ignored cmd start (already started).\n");
	cmd = CMD_NONE;
      }
      
      //read a packet from the data socket and write it to the ring buffer
      if(FD_ISSET(raw.svc,&readfds)) {
	nbytes = recvfrom(raw.svc, buf, BUFSIZE, 0, (struct sockaddr *)&(raw.rem_addr), &(raw.alen));

	if(nbytes == BUFSIZE) {
	  //fwrite(buf + trim, recvlen-trim, 1, out);
	  status = ipcio_write(&data_block,buf+UDP_HDR_SIZE,VDIF_PKT_SIZE);
	  //fprintf(stderr,"ipcio_write: %d bytes\n",status);

	  //print VDIF frame header
	  //printVDIFHeader((vdif_header *)(buf+UDP_HDR_SIZE), VDIFHeaderPrintLevelLong);
	  //printVDIFHeader((vdif_header *)(buf+UDP_HDR_SIZE), VDIFHeaderPrintLevelColumns);
	  //printVDIFHeader((vdif_header *)(buf+UDP_HDR_SIZE), VDIFHeaderPrintLevelShort);
	  //fprintf(stderr,"VDIFFrame MJD: %d Number: %d\n",getVDIFFrameMJD((vdif_header *)(buf+UDP_HDR_SIZE)), getVDIFFrameNumber((vdif_header *)(buf+UDP_HDR_SIZE)));
	  framenumtmp = getVDIFFrameNumber((vdif_header *)(buf+UDP_HDR_SIZE));
	  threadid = getVDIFThreadID((vdif_header *)(buf+UDP_HDR_SIZE));
	  framediff = framenumtmp - framenum[threadid];

	  if(framediff != -MAXFRAMENUM && framenum[threadid] != -1 && framediff != 1) {
	  //if(framediff != -25599 && abs(framediff) > 1 && framenum[threadid] != -1) {
	    currt = time(NULL);
	    tmpt = localtime(&currt);
	    strftime(currt_string,sizeof(currt_string), "%Y-%m-%d %H:%M:%S", tmpt);
	    fprintf(skiplogfd,"%s FRAME SKIP FROM %d to %d (THREAD %d)\n",currt_string,framenum[threadid],framenumtmp,threadid);
	    fflush(skiplogfd);
	  }
	  else if(framenum[threadid] == -1) {
	    
	    fprintf(skiplogfd,"Writer: Thread %d First frame: %d\n",threadid,framenumtmp);
	    fflush(skiplogfd);
	  }

	  framenum[threadid] = framenumtmp;

	}
	else if(nbytes <= 0) {
	  fprintf(stderr,"Raw socket read failed: %d\n.", nbytes);
	}
	/*
	else 
	  fprintf(stderr,"Received packet size: %d, ignoring.\n", nbytes);
	*/
      }
 
      //XXX: check for overflow of the data block here?
      //nbytes = fread(buf,1,BUFSIZE,infd);
      //fprintf(stderr,"fread: %d bytes\n",nbytes);
      //status = ipcio_write(&data_block,buf,nbytes);
      //fprintf(stderr,"ipcio_write: %d bytes\n",status);
      
      //sleep(2);
    }
  }
  
  //fclose(infd);
  
  return 0;
}
static void select_loop(libvchan_t *vchan)
{
    fd_set select_set;
    fd_set wr_set;
    int max_fd;
    int ret;
    int vchan_fd;
    sigset_t selectmask;
    struct timespec zero_timeout = { 0, 0 };
    struct timespec select_timeout = { 10, 0 };
    struct buffer stdin_buf;

    sigemptyset(&selectmask);
    sigaddset(&selectmask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &selectmask, NULL);
    sigemptyset(&selectmask);
    buffer_init(&stdin_buf);
    /* remember to set back to blocking mode before closing the FD - this may
     * be not the only copy and some processes may misbehave when get
     * nonblocking FD for input/output
     */
    set_nonblock(local_stdin_fd);

    for (;;) {
        vchan_fd = libvchan_fd_for_select(vchan);
        FD_ZERO(&select_set);
        FD_ZERO(&wr_set);
        FD_SET(vchan_fd, &select_set);
        max_fd = vchan_fd;
        if (local_stdout_fd != -1 &&
                (size_t)libvchan_buffer_space(vchan) > sizeof(struct msg_header)) {
            FD_SET(local_stdout_fd, &select_set);
            if (local_stdout_fd > max_fd)
                max_fd = local_stdout_fd;
        }
        if (child_exited && local_stdout_fd == -1)
            check_child_status(vchan);
        if (local_stdin_fd != -1 && buffer_len(&stdin_buf)) {
            FD_SET(local_stdin_fd, &wr_set);
            if (local_stdin_fd > max_fd)
                max_fd = local_stdin_fd;
        }
        if ((local_stdin_fd == -1 || buffer_len(&stdin_buf) == 0) &&
                libvchan_data_ready(vchan) > 0) {
            /* check for other FDs, but exit immediately */
            ret = pselect(max_fd + 1, &select_set, &wr_set, NULL,
                    &zero_timeout, &selectmask);
        } else
            ret = pselect(max_fd + 1, &select_set, &wr_set, NULL,
                    &select_timeout, &selectmask);
        if (ret < 0) {
            if (errno == EINTR && local_pid > 0) {
                continue;
            } else {
                perror("select");
                do_exit(1);
            }
        }
        if (ret == 0) {
            if (!libvchan_is_open(vchan)) {
                /* remote disconnected witout a proper signaling */
                do_exit(1);
            }
        }
        if (FD_ISSET(vchan_fd, &select_set))
            libvchan_wait(vchan);
        if (buffer_len(&stdin_buf) &&
                local_stdin_fd != -1 &&
                FD_ISSET(local_stdin_fd, &wr_set)) {
            if (flush_client_data(local_stdin_fd, &stdin_buf) == WRITE_STDIN_ERROR) {
                perror("write stdin");
                close(local_stdin_fd);
                local_stdin_fd = -1;
            }
        }
        while (libvchan_data_ready(vchan))
            if (handle_vchan_data(vchan, &stdin_buf) != WRITE_STDIN_OK)
                break;

        if (local_stdout_fd != -1
                && FD_ISSET(local_stdout_fd, &select_set))
            handle_input(vchan);
    }
}
Example #19
0
void maitreClient(){
    fd_set fdread;
    struct timeval tv;
    int n,i,r,m,start;
#ifdef DEBUG
    char dbg[16];
#endif
    struct flock lock;
    int t;

    maitreLecteur=dp.maitre[0];
    FD_ZERO(&fdread);
    tv.tv_sec = 50;
    tv.tv_usec = 0;
    n=fdServeur>maitreLecteur?fdServeur:maitreLecteur;
    printf("Maitre CLient - fdServeur=%d\n", fdServeur);
    while(1){
        /* On ajoute les descripteurs esclave et serveur */
        /* Add slave and server pipe file descriptors */
        FD_ZERO(&fdread);
        FD_SET(fdServeur,&fdread);
        FD_SET(maitreLecteur,&fdread);
        r=select(n+1, &fdread, NULL, NULL,&tv);
        if(r<0){    
            perror("select:\n");
            continue;
        }
        if(r==0){
            exit(0);
        }

        if(FD_ISSET(fdServeur, &fdread)){
            /* On vient de recevoir une information du serveur
             * On la retransmet aux esclaves
             */
            /* We just have received information from the server.
             * We repeat it to slaves.
             */
            i=readFromServer(message);
            t=message[0];
            switch(t){
                case 'L':
                    /* Instruction : Lock. Dans ce cas il faut envoyer a chaque processus une section differente a locker */
                    /* Lock instruction. We need to send a different section to lock to each process */
                    
                    unSerialiseFLock(&lock);
                    start=lock.l_start;
                    for(i=0;i<dp.nclnt;i++){
                        lock.l_start=start+i;
                        serialiseFLock(&lock);
                        write(dp.lclnt[i][1], message,M_SIZE);
                    }
                    printf("\n");
                    continue;
                case 'T':
                    /* Instruction: Test. Il s'agit d'une trame annoncant un nouveau test : on verifie qu'il ne s'agit pas d'une 
                     * demande de FIN des tests
                     */
                    /* Test instruction. Ensure server is not sending the FIN(ish) instruction to end tests */

                    /* A re-ecrire un peu mieux des que possible */
                    /* To be rewritten asap*/
                    m=atoi(&(message[2]));
                    if(m==FIN)        
                        break;
                    if(m==CLEAN)
                        printf("\n");
                    

                
            serverSendLocal();
            continue;
            }
            break;
        }else{
            /* Dans le cas inverse, on lis les esclaves et on remonte l'information au serveur 
             */
            /* Else, we read information from slaves and repeat them to the server */
            for(i=0;i<dp.nclnt;i++){
                r=read(maitreLecteur, message,M_SIZE );
                r=write(fdServeur,message,M_SIZE );
                if(r<0)perror("write : ");
                    
            }
            continue;
        }
    }

    /* On vient de recevoir la trame FIN de programme */
    /* Receive the FIN(ish) instruction*/

    /* On la communique a tous les esclaves */
    /* Repeat it to the slaves */
    printf("Fin du programme en cours...\n");
    serverSendLocal();

    /* Et c'est fini! */
    /* Ok, we can quit */
    printf("Bye :)\n");

    
}
Example #20
0
    void Run()
	{
		break_ = false;

		// configure the master fd_set for select()

		fd_set masterfds, tempfds;
		FD_ZERO( &masterfds );
		FD_ZERO( &tempfds );

		// in addition to listening to the inbound sockets we
		// also listen to the asynchronous break pipe, so that AsynchronousBreak()
		// can break us out of select() from another thread.
		FD_SET( breakPipe_[0], &masterfds );
		int fdmax = breakPipe_[0];

		for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
				i != socketListeners_.end(); ++i ){

			if( fdmax < i->second->impl_->Socket() )
				fdmax = i->second->impl_->Socket();
			FD_SET( i->second->impl_->Socket(), &masterfds );
		}


		// configure the timer queue
		double currentTimeMs = GetCurrentTimeMs();

		// expiry time ms, listener
		std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
		for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
				i != timerListeners_.end(); ++i )
			timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
		std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );

		const int MAX_BUFFER_SIZE = 4098;
		char *data = new char[ MAX_BUFFER_SIZE ];
		IpEndpointName remoteEndpoint;

		struct timeval timeout;

		while( !break_ ){
			tempfds = masterfds;

			struct timeval *timeoutPtr = 0;
			if( !timerQueue_.empty() ){
				double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs();
				if( timeoutMs < 0 )
					timeoutMs = 0;

				// 1000000 microseconds in a second
				timeout.tv_sec = (long)(timeoutMs * .001);
				timeout.tv_usec = (long)((timeoutMs - (timeout.tv_sec * 1000)) * 1000);
				timeoutPtr = &timeout;
			}

			if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 && errno != EINTR ){
   				throw std::runtime_error("select failed\n");
			}

			if ( FD_ISSET( breakPipe_[0], &tempfds ) ){
				// clear pending data from the asynchronous break pipe
				char c;
				if (read( breakPipe_[0], &c, 1 ) < 0) {
				  fprintf(stderr, "Could not read from osc pipe.\n");
		    }
			}

			if( break_ )
				break;

			for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
					i != socketListeners_.end(); ++i ){

				if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){

					int size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
					if( size > 0 ){
						i->first->ProcessPacket( data, size, remoteEndpoint );
						if( break_ )
							break;
					}
				}
			}

			// execute any expired timers
			currentTimeMs = GetCurrentTimeMs();
			bool resort = false;
			for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
					i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){

				i->second.listener->TimerExpired();
				if( break_ )
					break;

				i->first += i->second.periodMs;
				resort = true;
			}
			if( resort )
				std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
		}

		delete [] data;
	}
Example #21
0
static void xmlrpc_handler(int fd)
{
  fd_set rfds;
  struct timeval tv;
  int ret, len, max = 0, loadlen = -1;
  char buffer[CONFIG_EXAMPLES_XMLRPC_BUFFERSIZE] = { 0 };
  char value[CONFIG_XMLRPC_STRINGSIZE + 1];
  char *temp;

  /* Read in the Request Header */

  do
    {
      FD_ZERO(&rfds);
      FD_SET(fd, &rfds);

      tv.tv_sec = 1;
      tv.tv_usec = 0;

      ndbg("[%d] select...\n", fd);
      ret = select(fd + 1, &rfds, NULL, NULL, &tv);
      ndbg("[%d] data ready\n", fd);

      if (ret > 0)
        {
          if (FD_ISSET(fd, &rfds))
            {
              len = recv(fd, &buffer[max], 1024, 0);
              ndbg("[%d] %d bytes received\n", fd, len);

              if (len > 0)
                {
                  max += len;
                  buffer[max] = 0;

                  ret = xmlrpc_getheader(buffer, "Content-Length:", value,
                                         CONFIG_EXAMPLES_XMLRPC_BUFFERSIZE);
                  if (ret > 0)
                    loadlen = atoi(value);
                }
              else
                {
                  ret = -1;
                  break;
                }
            }
        }
      else
        {
          /* Timeout... */

          ndbg("[%d] timeout\n", fd);
          ret = -1;
          break;
        }

      temp = strstr(buffer, separator);

      if (temp)
        {
          if (strlen(temp) - 4 == loadlen)
            break;
        }

    }
  while (1);

  /* Determine request */

  if (!strncmp(buffer, "POST", 4))
    {
      temp = xmlrpc_findbody(buffer);
      xmlrpc_parse(fd, temp);
    }
  else
    {
      write(fd, notimplemented, strlen(notimplemented));
    }
}
Example #22
0
bool KPtyDevicePrivate::doWait(int msecs, bool reading)
{
    Q_Q(KPtyDevice);
#ifndef __linux__
    struct timeval etv;
#endif
    struct timeval tv, *tvp;

    if (msecs < 0)
        tvp = nullptr;
    else {
        tv.tv_sec = msecs / 1000;
        tv.tv_usec = (msecs % 1000) * 1000;
#ifndef __linux__
        gettimeofday(&etv, 0);
        timeradd(&tv, &etv, &etv);
#endif
        tvp = &tv;
    }

    while (reading ? readNotifier->isEnabled() : !writeBuffer.isEmpty()) {
        fd_set rfds;
        fd_set wfds;

        FD_ZERO(&rfds);
        FD_ZERO(&wfds);

        if (readNotifier->isEnabled())
            FD_SET(q->masterFd(), &rfds);
        if (!writeBuffer.isEmpty())
            FD_SET(q->masterFd(), &wfds);

#ifndef __linux__
        if (tvp) {
            gettimeofday(&tv, 0);
            timersub(&etv, &tv, &tv);
            if (tv.tv_sec < 0)
                tv.tv_sec = tv.tv_usec = 0;
        }
#endif

        switch (select(q->masterFd() + 1, &rfds, &wfds, nullptr, tvp)) {
        case -1:
            if (errno == EINTR)
                break;
            return false;
        case 0:
            q->setErrorString(QLatin1String("PTY operation timed out"));
            return false;
        default:
            if (FD_ISSET(q->masterFd(), &rfds)) {
                bool canRead = _k_canRead();
                if (reading && canRead)
                    return true;
            }
            if (FD_ISSET(q->masterFd(), &wfds)) {
                bool canWrite = _k_canWrite();
                if (!reading)
                    return canWrite;
            }
            break;
        }
    }
    return false;
}
Example #23
0
/// 小数据量的收发,集中在一个线程里,不影响效率
void CTcpSock::P_ThreadWork()
{
	byte  bytLvl = 0;
	char  szBuf[100] = {0};
	DWORD dwLen = 0;
	DWORD dwPushTm;
	DWORD dwBufSize = (DWORD)sizeof(szBuf);
	bool  bMustConn = false;
	int   iFlag;
	int   iret;
	int   iConnFailTimes = 0;	// 连续连接失败次数
	static DWORD sta_dwLastConTm = GetTickCount();

	fd_set rset, wset, eset;
	struct timeval tval;

	int  iRecvLen;
	char szRecvbuf[ TCP_RECVSIZE+1 ];

	char  szSendBuf[ TCP_SENDSIZE ] = {0};
	DWORD dwSendLen;
	//DWORD dwPushTm = 0;
	//BYTE  bytLvl;

	szRecvbuf[0] = 0x00;		// 0x00 表示中心TCP协议帧

	DWORD dwSleep = 500; // ms
	while(!g_bProgExit)
	{
		usleep(dwSleep * 1000);

		dwSleep = 500;
		if( 0 == m_objSockStaMng.PopData(bytLvl, dwBufSize, dwLen, szBuf, dwPushTm) )
		{
			switch(szBuf[0])
			{
				case 0x01:
					{
						iConnFailTimes = 0;
						m_bytSockSta = DisConn;
						bMustConn = true;
					}
					break;
	
				default:
					break;
			}
		}

		switch( m_bytSockSta )
		{
			case Idle:
				{
					// 若处于空闲状态,则每隔60秒连接一次中心
					if( GetTickCount() - sta_dwLastConTm >= 60000 )
					{
						m_bytSockSta = Conn;
						break;
					}
	
					if( bMustConn == true )
					{
						m_bytSockSta = Conn;
						bMustConn = false;
						break;
					}
				}
				break;
	
			case Conn:
				{
					sta_dwLastConTm = GetTickCount();

					// 若没有可用的临时IP,说明要连接到登陆服务器,此时则使用配置区中的IP
					if( m_dwSymb == DEV_DVR )
					{
						for(int i=0; i<m_iIPCnt; i++)
						{
							if( m_bIPEnabled[i] )
							{
								m_bIPEnabled[i] = false;	// 使用一次后即置为假
								m_conn.sin_family = AF_INET;
								m_conn.sin_port = m_usTempTcpPort[i];
								m_conn.sin_addr.s_addr = m_ulTempIP[i];
								
								// 且DVR UDP的地址和端口也要相应更改
								g_objDvrUdp.m_ulIp = m_ulTempIP[i];
								g_objDvrUdp.m_usPort = m_usTempUdpPort[i];
								tag1QIpCfg	obj1QIpCfg;
								GetImpCfg( &obj1QIpCfg, sizeof(obj1QIpCfg), offsetof(tagImportantCfg, m_uni1QComuCfg.m_ary1QIpCfg[0]), sizeof(obj1QIpCfg) );
								obj1QIpCfg.m_ulVUdpIP = g_objDvrUdp.m_ulIp;
								obj1QIpCfg.m_usVUdpPort = g_objDvrUdp.m_usPort;
								SetImpCfg( &obj1QIpCfg, offsetof(tagImportantCfg, m_uni1QComuCfg.m_ary1QIpCfg[0]), sizeof(obj1QIpCfg) );

								goto TCP_CONNECT;
							}
						}
					}
					
					// 读取IP、端口配置
					tag1QIpCfg obj1QIpCfg[2];
					tag1PComuCfg obj1PComuCfg;
					tag1LComuCfg obj1LComuCfg;
					if(	GetImpCfg( (void*)&obj1QIpCfg, sizeof(obj1QIpCfg), offsetof(tagImportantCfg, m_uni1QComuCfg.m_ary1QIpCfg), sizeof(obj1QIpCfg) )
						|| GetImpCfg( (void*)&obj1PComuCfg, sizeof(obj1PComuCfg), offsetof(tagImportantCfg, m_uni1PComuCfg.m_obj1PComuCfg), sizeof(obj1PComuCfg) )
						|| GetImpCfg( (void*)&obj1LComuCfg, sizeof(obj1LComuCfg), offsetof(tagImportantCfg, m_uni1LComuCfg.m_obj1LComuCfg), sizeof(obj1LComuCfg) )
						)
					{
						PRTMSG(MSG_ERR, "Read IP Cfg Fail\n" );
						m_bytSockSta = Idle;
						break;
					}
					
					m_conn.sin_family = AF_INET;
					switch( m_dwSymb )
					{
					case DEV_QIAN: // king中心
						{
							m_conn.sin_port = obj1QIpCfg[0].m_usQianTcpPort;
	 						m_conn.sin_addr.s_addr = obj1QIpCfg[0].m_ulQianTcpIP;
						}
						break;

					case DEV_DVR:	// 独立视频服务器
						{
							m_conn.sin_port = obj1QIpCfg[1].m_usQianTcpPort;
	 						m_conn.sin_addr.s_addr = obj1QIpCfg[1].m_ulQianTcpIP;
						}
						break;

					case DEV_UPDATE: // 管理平台 (应该增加一个新的标记,待)
						{
							m_conn.sin_port = obj1LComuCfg.m_usLiuPort2;
	 						m_conn.sin_addr.s_addr = obj1LComuCfg.m_ulLiuIP2;
						}
						break;

					default:
						break;
					}

TCP_CONNECT:					
					// 若配置为空,则返回
					if(	0 == m_conn.sin_addr.s_addr	|| 0 == m_conn.sin_port || 0 == strcmp(obj1PComuCfg.m_szTel, ""))
					{
						PRTMSG(MSG_ERR, "IP/Port/Tel Cfg Is Uncompleted!\n");
						G_RecordDebugInfo("IP/Port/Tel Cfg Is Uncompleted!\n");
						m_bytSockSta = Idle;
						break;
					}
	
					// 确认关闭已有连接
					if( -1 != m_sockTcp )
					{
						shutdown(m_sockTcp, 2);
						close(m_sockTcp);
						m_sockTcp = -1;
					}
	
					m_sockTcp = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
					if( -1 == m_sockTcp )
					{
						PRTMSG(MSG_ERR, "Socket err\n" );
						break;
					}
	
					bzero(&(m_conn.sin_zero),8);
	
					// 获取当前socket的属性, 并设置noblocking属性
					iFlag = fcntl(m_sockTcp, F_GETFL, 0);
					fcntl(m_sockTcp, F_SETFL, iFlag | O_NONBLOCK);

					LINGER ling;
					ling.l_onoff = 1; // closesocket时强制关闭并立即释放套接字资源
					ling.l_linger = 0;
					::setsockopt( m_sockTcp, SOL_SOCKET, SO_LINGER, (char*)&ling, sizeof(ling) );

					BOOL blVal = TRUE; // 禁止Nagle算法
					setsockopt( m_sockTcp, IPPROTO_TCP, TCP_NODELAY, (char*)&blVal, sizeof(blVal) );
	
					if( DEV_QIAN == m_dwSymb )
					{
						PRTMSG(MSG_DBG, "Qian Tcp connect: Tel: %s, IP: %s, Port: %d\n", obj1PComuCfg.m_szTel, inet_ntoa(m_conn.sin_addr), htons(m_conn.sin_port));
						RenewMemInfo(0x02, 0x02, 0x01, 0x03);

						G_RecordDebugInfo("Qian Tcp connect: Tel: %s, IP: %s, Port: %d", obj1PComuCfg.m_szTel, inet_ntoa(m_conn.sin_addr), htons(m_conn.sin_port));
					}
					if(DEV_DVR == m_dwSymb)
					{
						PRTMSG(MSG_DBG, "Dvr Tcp connect: Tel: %s, IP: %s, Port: %d\n", obj1PComuCfg.m_szTel, inet_ntoa(m_conn.sin_addr), htons(m_conn.sin_port));
					
						G_RecordDebugInfo("Dvr Tcp connect: Tel: %s, IP: %s, Port: %d", obj1PComuCfg.m_szTel, inet_ntoa(m_conn.sin_addr), htons(m_conn.sin_port));
					}
					
					if( (iret = connect( m_sockTcp, (struct sockaddr *)&m_conn, sizeof(struct sockaddr))) < 0 )
					{
						if(errno != EINPROGRESS)
						{
							PRTMSG(MSG_DBG, "connect failed, errno=%d\n", errno);	
							G_RecordDebugInfo("connect failed, errno=%d", errno);	
							perror("");
	
							iConnFailTimes++;
							if( !_JudgeConFailMaxTime(iConnFailTimes) )
							{
								sta_dwLastConTm = GetTickCount() - 57000; // 这样,3秒后可以尝试重新connect,提高效率
							}

							m_bytSockSta = Idle;
							break;
						}
					}
					m_bytSockSta = WaitConn;
				}
				break;
	
			case WaitConn:
				{
					FD_ZERO(&rset);
					FD_ZERO(&wset);
					FD_ZERO(&eset);
					FD_SET(m_sockTcp, &rset);
					FD_SET(m_sockTcp, &wset);
					FD_SET(m_sockTcp, &eset);
	
					tval.tv_sec = 30;
					tval.tv_usec = 0;
	
					iret = select(m_sockTcp+1, &rset, &wset, &eset, &tval);
					if( 0 == iret )
					{
						if( m_dwSymb == DEV_QIAN )
						{
							PRTMSG(MSG_NOR, "Qian Tcp Socket connect time out!\n");
							G_RecordDebugInfo("Tcp Socket connect time out!");
						}

						if( m_dwSymb == DEV_DVR )
						{
							PRTMSG(MSG_NOR, "Dvr Tcp Socket connect time out!\n");
							G_RecordDebugInfo("Dvr Tcp Socket connect time out!");
						}

						goto _CUR_CONNECT_FAIL;
					}
					else if(iret < 0)
					{
						PRTMSG(MSG_NOR, "Tcp Socket select err!\n");
						goto _CUR_CONNECT_FAIL;
					}
					else
					{
						if( FD_ISSET(m_sockTcp, &eset) )
						{
							PRTMSG(MSG_NOR, "Tcp Socket connect except!\n");
							goto _CUR_CONNECT_FAIL;
						}
						else if(FD_ISSET(m_sockTcp, &rset) || FD_ISSET(m_sockTcp, &wset)) 
						{
							m_bConnect = true;
							iConnFailTimes = 0;							

							if( m_dwSymb == DEV_QIAN )
							{
								PRTMSG(MSG_NOR, "Qian Tcp Socket Connect succ!\n");
								G_RecordDebugInfo("Qian Tcp Socket Connect succ!");
							}
							if( m_dwSymb == DEV_DVR )
							{
								PRTMSG(MSG_NOR, "Dvr Socket Connect succ!\n");
								G_RecordDebugInfo("Dvr Tcp Socket Connect succ!");
							}

							if(m_dwSymb == DEV_DVR)
							{
								for(int i=0; i<MAX_TEMP_IP_CNT; i++)
									m_bIPEnabled[i] = false;
							}

							// 通知连接成功
							char szbuf[2];
							szbuf[0] = 0x01;	// 0x01 表示非中心协议帧
							szbuf[1] = 0x01;	// 0x01 表示TCP套接字连接成功
							DataPush((void*)szbuf, 2, DEV_SOCK, m_dwSymb, LV3);
							
							RenewMemInfo(0x02, 0x01, 0x01, 0x01);
							
							m_bytSockSta = Working;
							break;	
						}
						else 
						{
							PRTMSG(MSG_ERR, "Tcp Socket select err: sockfd not set\n" );
							goto _CUR_CONNECT_FAIL;
						}
					}
					break;

_CUR_CONNECT_FAIL:
					close(m_sockTcp);
					m_sockTcp = -1;
					
					iConnFailTimes++;
					if( !_JudgeConFailMaxTime(iConnFailTimes) )
					{
						sta_dwLastConTm = GetTickCount() - 57000; // 这样,3秒后可以尝试重新connect,提高效率
					}
					
					m_bytSockSta = DisConn;
				}
				break;
	
			case Working:
				{
					/// 先写

					FD_ZERO(&wset);
					FD_ZERO(&eset);
					FD_SET(m_sockTcp, &wset);
					FD_SET(m_sockTcp, &eset);
	
					tval.tv_sec = 0;
					tval.tv_usec = 0;

					iret = select(m_sockTcp+1, NULL, &wset, &eset, &tval);
					if( iret > 0 )
					{
						if( FD_ISSET(m_sockTcp, &eset) )
						{
							PRTMSG(MSG_NOR, "Tcp Socket select write except!\n");
							G_RecordDebugInfo("Tcp Socket select write except!");
							goto _CUR_SOCK_EXCEPT;
						}
						else if( FD_ISSET(m_sockTcp, &wset) )
						{
							if( 0 == m_objSendMng.PopData( bytLvl, sizeof(szSendBuf), dwSendLen, szSendBuf, dwPushTm) )
							{
								if( dwSendLen > 0 && dwSendLen <= sizeof(szSendBuf) && -1 != m_sockTcp )
								{
									iret = send( m_sockTcp, szSendBuf, dwSendLen, 0 );
									
									if( iret > 0 )
									{
										if( DEV_QIAN == m_dwSymb )
										{
											PRTMSG(MSG_DBG, "Qian TcpSock send:");
										}
										if( DEV_DVR == m_dwSymb )
										{
											PRTMSG(MSG_DBG, "Dvr TcpSock send:");
										}
										PrintString(szSendBuf,iret);
									}
									else if( iret < 0 )
									{
										goto _CUR_SOCK_EXCEPT;
									}
								}

								dwSleep = 50;
							}
						}
						else
						{
							goto _CUR_SOCK_EXCEPT;
						}
					}
					else if( 0 == iret )
					{
						PRTMSG(MSG_NOR, "Tcp Socket select write block!\n");
						G_RecordDebugInfo("Tcp Socket select write block!");
					}
					else if(iret < 0)
					{
						PRTMSG(MSG_NOR, "Tcp Socket select write err!\n");
						G_RecordDebugInfo("Tcp Socket select write err!");
						goto _CUR_SOCK_EXCEPT;
					}


					/// 后读

					FD_ZERO(&rset);
					FD_ZERO(&eset);
					FD_SET(m_sockTcp, &rset);
					FD_SET(m_sockTcp, &eset);
					
					tval.tv_sec = 0;
					tval.tv_usec = 0;

					iret = select(m_sockTcp+1, &rset, NULL, &eset, &tval);
					if( iret > 0 )
					{
						if( FD_ISSET(m_sockTcp, &eset) )
						{
							PRTMSG(MSG_NOR, "Tcp Socket select read except!\n");
							G_RecordDebugInfo("Tcp Socket select read except!");
							goto _CUR_SOCK_EXCEPT;
						}
						else if( FD_ISSET(m_sockTcp, &rset) )
						{
							iRecvLen = recv( m_sockTcp, szRecvbuf+1, sizeof(szRecvbuf)-1, 0 );
						
							if( iRecvLen > 0 )
							{
								if( DEV_QIAN == m_dwSymb )
								{
									PRTMSG(MSG_NOR, "Qian Rcv Tcp Msg: ");
								}
								if( DEV_DVR == m_dwSymb )
								{
									PRTMSG(MSG_NOR, "Dvr Rcv Tcp Msg: ");
								}
								PrintString(szRecvbuf+1, iRecvLen);
								
								DataPush(szRecvbuf, iRecvLen+1, DEV_SOCK, m_dwSymb, LV2);

								dwSleep = 50;
							}
							else
							{
								if(m_dwSymb == DEV_DVR)
								{
									PRTMSG(MSG_ERR, "Dvr Tcp socket recv err!\n");								
									G_RecordDebugInfo("Dvr Tcp socket recv err, errno=%d", errno);
								}
								if(m_dwSymb == DEV_QIAN)
								{
									PRTMSG(MSG_ERR, "Qian Tcp socket recv err!\n");								
									G_RecordDebugInfo("Qian Tcp socket recv err, errno=%d", errno);
								}
								
								perror("");
								goto _CUR_SOCK_EXCEPT;
							}
						}
					}
					else if( iret < 0 )
					{
						PRTMSG(MSG_ERR, "Tcp socket select err!\n");
						G_RecordDebugInfo("Tcp socket select err!");
						perror("");
						goto _CUR_SOCK_EXCEPT;
					}

					break;

_CUR_SOCK_EXCEPT:
					sta_dwLastConTm = GetTickCount() - 57000; // 这样,3秒后可以尝试重新connect,提高效率
					m_bytSockSta = DisConn;
				}
				break;
	
			case DisConn:
				{
					if( m_dwSymb == DEV_QIAN )
						G_RecordDebugInfo("Qian Tcp socket Disconn!");
					if( m_dwSymb == DEV_DVR )
						G_RecordDebugInfo("Dvr Tcp socket Disconn!");

					if(m_sockTcp > 0)
					{
						shutdown(m_sockTcp, 2);
						close(m_sockTcp);
						m_sockTcp = -1;
					}
	
					// Tcp断开连接,则把Udp也断开
					if( DEV_QIAN == m_dwSymb )
					{
						g_objQianUdp.ReqDestroySock();
					}
					if( DEV_DVR == m_dwSymb )
					{
						g_objDvrUdp.ReqDestroySock();
					}

					// 通知断开连接
					char szbuf[2];
					szbuf[0] = 0x01;	// 0x01 表示非中心协议帧
					szbuf[1] = 0x02;	// 0x02 表示通知网络断开连接
					DataPush((void*)szbuf, 2, DEV_SOCK, m_dwSymb, LV3);
					
					RenewMemInfo(0x02, 0x01, 0x01, 0x00);
	
					m_bytSockSta = Idle;
				}
				break;
	
			default:
				{
					m_bytSockSta = Idle;
				}
				break;
		}
	}
}
Example #24
0
static void connectServer(const char *stty, const char *dev) {
  int fdmax, newfd;

  fd_set master, read_fds;
  FD_ZERO(&master);
  FD_ZERO(&read_fds);

  int serverfd;
  serverfd = createServerSocket(dev);
  if (serverfd < 0) {
    syslog(LOG_ERR, "mTerm_server: Failed to create server socket\n");
    return;
  }

  struct ttyRaw* tty_sol;
  tty_sol = setTty(openTty(stty), 1);
  if (!tty_sol) {
    syslog(LOG_ERR, "mTerm_server: Failed to set tty to raw mode\n");
    close(serverfd);
    return;
  }

  struct bufStore* buf;
  buf = createBuffer(dev, FILE_SIZE_BYTES);
  if (!buf || (buf->buf_fd < 0)) {
    syslog(LOG_ERR, "mTerm_server: Failed to create the log file\n");
    closeTty(tty_sol);
    close(serverfd);
    return;
  }

  FD_SET(serverfd, &master);
  FD_SET(tty_sol->fd,&master);
  fdmax = (serverfd > tty_sol->fd) ? serverfd : tty_sol->fd;

  for(;;) {
    read_fds = master;
    if (select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1) {
      syslog(LOG_ERR, "mTerm_server: Server socket: select error\n");
      break;
    }
    if (FD_ISSET(serverfd, &read_fds)) {
      newfd = acceptClient(serverfd);
      if (newfd < 0) {
        syslog(LOG_ERR, "mTerm_server: Error on accepting client\n");
      } else {
        FD_SET(newfd, &master);
        if (newfd > fdmax) {
          fdmax = newfd;
        }
      }
    }
    if (FD_ISSET(tty_sol->fd, &read_fds)) {
      if ( processSol(&master, serverfd, fdmax, tty_sol->fd, buf) < 0) {
        break;
      }
    }
    int i;
    for(i = 0; i <= fdmax; i++) {
      if (FD_ISSET(i, &read_fds)) {
        if ((i == serverfd) || (i == tty_sol->fd)) {
          continue;
        } else {
          processClient(&master, i, tty_sol->fd, buf);
        }
      }
    }
  }
  closeTty(tty_sol);
  close(serverfd);
  closeBuffer(buf);
}
Example #25
0
void interconnect_stream (FILE *sock_in, FILE *sock_out, int sock_fd) {
  /* 具体的には、以下の挙動をすれば良いと思われる。
   * - selectを使って、stdin(STDIN_FILENO)とソケットのどちらかから
   *   データが読み取れる状態になるのを待つ。
   * -- stdin(STDIN_FILENO)が読み出しokになったら、
   *    読み出せる限り読み出して、それをソケットに書き出す。
   * -- ソケットが読み出しokになったら、
   *    読み出せる限り読み出して、それをstdoutに書き出す。
   * -- どちらかがEOFまたは何からのエラーが来たら、それに応じた終了処理を行う
   */

  /* sigmaskを生成する
   * ……が、前提として、予めSIGPIPEは無視してある、という事にする。
   * ここでは省略する。 */
  /* SIGPIPEを無視する事については以下を参照
   * http://www.kt.rim.or.jp/~ksk/sock-faq/unix-socket-faq-ja-2.html#ss2.19 */


  /* stdinのEOFはフラグ管理する必要がある */
  char stdin_is_eof = 0;

  while (1) {
    /* nfdsを生成する */
    int nfds;
    if (stdin_is_eof) {
      nfds = sock_fd + 1;
    }
    else {
      nfds = ((STDIN_FILENO < sock_fd) ? sock_fd : STDIN_FILENO) + 1;
    }

    /* fd_setを生成する */
    fd_set readfds;
    FD_ZERO(&readfds);
    if (!stdin_is_eof) FD_SET(STDIN_FILENO, &readfds);
    FD_SET(sock_fd, &readfds);

    /* timevalを生成する(man 2 selectによると、
     * select時にtimeoutが破壊される環境があるらしいので毎回生成する) */
    struct timeval timeout;
    timeout.tv_sec = SELECT_TIMEOUT; /* 秒 */
    timeout.tv_usec = 0; /* マイクロ秒 */

    /* selectを実行する */
    int r = select(nfds, &readfds, NULL, NULL, &timeout);
    if (r == -1) {
      if (errno == EINTR) {
        /* シグナルを受信した */
        /* とりあえず終了でいいと思う */
        perror("caught a signal");
        break;
      }
      else {
        /* よく分からないエラー */
        /* エラー内容をstderrに書き出す必要がある */
        perror("unknown error in select");
        break;
      }
    }
    if (!FD_ISSET(sock_fd, &readfds)
        && (stdin_is_eof || !FD_ISSET(STDIN_FILENO, &readfds))) {
      /* エラーでもないし、読み取り可能にもなってない状況なら、
       * タイムアウトしたものと考えられる。
       * (本来ならcontinue等を使って分かりやすい構造にしたいが、
       *  ソケットとstdinが同時の読み取り可能になった時に、
       *  片方に偏らせたくないので、
       *  一回のselectで両方とも処理可能にする為に、
       *  こんなややっこしい構造になってしまった)
       * 尚、この処理は、下のstdin確認よりも先にチェックする必要がある。
       * (stdin確認の内部でstdin_is_eofフラグを変更している為) */
      fprintf(stderr, "socket response timeout\n");
      break;
    }
    if (FD_ISSET(sock_fd, &readfds)) {
      /* ソケットから読み取り可能 */
      /* 適当に読み取り、読み取った分をstdoutに書き出す */
      int r = stream_transfer(sock_in, stdout);
      if (r <= 0) {
        /* socketがEOFになったら、stdoutのcloseを行う
         * (実際には不要だが、一応しておく) */
        fclose(stdout);
        break; /* ソケットがEOFになったら即終了 */
      }
    }
    if (!stdin_is_eof && FD_ISSET(STDIN_FILENO, &readfds)) {
      /* stdinから読み取り可能 */
      /* 適当に読み取り、読み取った分をソケットに書き出す */
      int r = stream_transfer(stdin, sock_out);
      if (r <= 0) {
        /* stdinがEOFになったら、sock_outのshutdownを行う
         * (closeするとreadの方までcloseされてしまうので、closeはしない) */
        fflush(sock_out);
        shutdown(sock_fd, SHUT_WR);
        stdin_is_eof = 1; /* stdinがEOFになっても即終了しない */
      }
    }
  }
  return;
}
Example #26
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  ipp_t		*event;			/* Event from scheduler */
  ipp_state_t	state;			/* IPP event state */
  char		scheme[32],		/* URI scheme ("rss") */
		username[256],		/* Username for remote RSS */
		host[1024],		/* Hostname for remote RSS */
		resource[1024],		/* RSS file */
		*options;		/* Options */
  int		port,			/* Port number for remote RSS */
		max_events;		/* Maximum number of events */
  http_t	*http;			/* Connection to remote server */
  http_status_t	status;			/* HTTP GET/PUT status code */
  char		filename[1024],		/* Local filename */
		newname[1024];		/* filename.N */
  cups_lang_t	*language;		/* Language information */
  ipp_attribute_t *printer_up_time,	/* Timestamp on event */
		*notify_sequence_number,/* Sequence number */
		*notify_printer_uri;	/* Printer URI */
  char		*subject,		/* Subject for notification message */
		*text,			/* Text for notification message */
		link_url[1024],		/* Link to printer */
		link_scheme[32],	/* Scheme for link */
		link_username[256],	/* Username for link */
		link_host[1024],	/* Host for link */
		link_resource[1024];	/* Resource for link */
  int		link_port;		/* Link port */
  cups_array_t	*rss;			/* RSS message array */
  _cups_rss_t	*msg;			/* RSS message */
  char		baseurl[1024];		/* Base URL */
  fd_set	input;			/* Input set for select() */
  struct timeval timeout;		/* Timeout for select() */
  int		changed;		/* Has the RSS data changed? */
  int		exit_status;		/* Exit status */


  fprintf(stderr, "DEBUG: argc=%d\n", argc);
  for (i = 0; i < argc; i ++)
    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);

 /*
  * See whether we are publishing this RSS feed locally or remotely...
  */

  if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme),
                      username, sizeof(username), host, sizeof(host), &port,
		      resource, sizeof(resource)) < HTTP_URI_OK)
  {
    fprintf(stderr, "ERROR: Bad RSS URI \"%s\"!\n", argv[1]);
    return (1);
  }

  max_events = 20;

  if ((options = strchr(resource, '?')) != NULL)
  {
    *options++ = '\0';

    if (!strncmp(options, "max_events=", 11))
    {
      max_events = atoi(options + 11);

      if (max_events <= 0)
        max_events = 20;
    }
  }

  rss = cupsArrayNew((cups_array_func_t)compare_rss, NULL);

  if (host[0])
  {
   /*
    * Remote feed, see if we can get the current file...
    */

    int	fd;				/* Temporary file */


    if ((rss_password = strchr(username, ':')) != NULL)
      *rss_password++ = '\0';

    cupsSetPasswordCB(password_cb);
    cupsSetUser(username);

    if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
    {
      fprintf(stderr, "ERROR: Unable to create temporary file: %s\n",
              strerror(errno));

      return (1);
    }

    if ((http = httpConnect(host, port)) == NULL)
    {
      fprintf(stderr, "ERROR: Unable to connect to %s on port %d: %s\n",
              host, port, strerror(errno));

      close(fd);
      unlink(filename);

      return (1);
    }

    status = cupsGetFd(http, resource, fd);

    close(fd);

    if (status != HTTP_OK && status != HTTP_NOT_FOUND)
    {
      fprintf(stderr, "ERROR: Unable to GET %s from %s on port %d: %d %s\n",
	      resource, host, port, status, httpStatus(status));

      httpClose(http);
      unlink(filename);

      return (1);
    }

    strlcpy(newname, filename, sizeof(newname));

    httpAssembleURI(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http",
                    NULL, host, port, resource);
  }
  else
  {
    const char	*cachedir,		/* CUPS_CACHEDIR */
		*server_name,		/* SERVER_NAME */
		*server_port;		/* SERVER_PORT */


    http = NULL;

    if ((cachedir = getenv("CUPS_CACHEDIR")) == NULL)
      cachedir = CUPS_CACHEDIR;

    if ((server_name = getenv("SERVER_NAME")) == NULL)
      server_name = "localhost";

    if ((server_port = getenv("SERVER_PORT")) == NULL)
      server_port = "631";

    snprintf(filename, sizeof(filename), "%s/rss%s", cachedir, resource);
    snprintf(newname, sizeof(newname), "%s.N", filename);

    httpAssembleURIf(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http",
                     NULL, server_name, atoi(server_port), "/rss%s", resource);
  }

 /*
  * Load the previous RSS file, if any...
  */

  load_rss(rss, filename);

  changed = cupsArrayCount(rss) == 0;

 /*
  * Localize for the user's chosen language...
  */

  language = cupsLangDefault();

 /*
  * Read events and update the RSS file until we are out of events.
  */

  for (exit_status = 0, event = NULL;;)
  {
    if (changed)
    {
     /*
      * Save the messages to the file again, uploading as needed...
      */

      if (save_rss(rss, newname, baseurl))
      {
	if (http)
	{
	 /*
          * Upload the RSS file...
	  */

          if ((status = cupsPutFile(http, resource, filename)) != HTTP_CREATED)
            fprintf(stderr, "ERROR: Unable to PUT %s from %s on port %d: %d %s\n",
	            resource, host, port, status, httpStatus(status));
	}
	else
	{
	 /*
          * Move the new RSS file over top the old one...
	  */

          if (rename(newname, filename))
            fprintf(stderr, "ERROR: Unable to rename %s to %s: %s\n",
	            newname, filename, strerror(errno));
	}

	changed = 0;
      }
    }

   /*
    * Wait up to 30 seconds for an event...
    */

    timeout.tv_sec  = 30;
    timeout.tv_usec = 0;

    FD_ZERO(&input);
    FD_SET(0, &input);

    if (select(1, &input, NULL, NULL, &timeout) < 0)
      continue;
    else if (!FD_ISSET(0, &input))
    {
      fprintf(stderr, "DEBUG: %s is bored, exiting...\n", argv[1]);
      break;
    }

   /*
    * Read the next event...
    */

    event = ippNew();
    while ((state = ippReadFile(0, event)) != IPP_DATA)
    {
      if (state <= IPP_IDLE)
        break;
    }

    if (state == IPP_ERROR)
      fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr);

    if (state <= IPP_IDLE)
      break;

   /*
    * Collect the info from the event...
    */

    printer_up_time        = ippFindAttribute(event, "printer-up-time",
                                              IPP_TAG_INTEGER);
    notify_sequence_number = ippFindAttribute(event, "notify-sequence-number",
                                	      IPP_TAG_INTEGER);
    notify_printer_uri     = ippFindAttribute(event, "notify-printer-uri",
                                	      IPP_TAG_URI);
    subject                = cupsNotifySubject(language, event);
    text                   = cupsNotifyText(language, event);

    if (printer_up_time && notify_sequence_number && subject && text)
    {
     /*
      * Create a new RSS message...
      */

      if (notify_printer_uri)
      {
        httpSeparateURI(HTTP_URI_CODING_ALL,
	                notify_printer_uri->values[0].string.text,
			link_scheme, sizeof(link_scheme),
                        link_username, sizeof(link_username),
			link_host, sizeof(link_host), &link_port,
		        link_resource, sizeof(link_resource));
        httpAssembleURI(HTTP_URI_CODING_ALL, link_url, sizeof(link_url),
	                "http", link_username, link_host, link_port,
			link_resource);
      }

      msg = new_message(notify_sequence_number->values[0].integer,
                        xml_escape(subject), xml_escape(text),
			notify_printer_uri ? xml_escape(link_url) : NULL,
			printer_up_time->values[0].integer);

      if (!msg)
      {
        fprintf(stderr, "ERROR: Unable to create message: %s\n",
	        strerror(errno));
        exit_status = 1;
	break;
      }

     /*
      * Add it to the array...
      */

      cupsArrayAdd(rss, msg);

      changed = 1;

     /*
      * Trim the array as needed...
      */

      while (cupsArrayCount(rss) > max_events)
      {
        msg = cupsArrayFirst(rss);

	cupsArrayRemove(rss, msg);

	delete_message(msg);
      }
    }

    if (subject)
      free(subject);

    if (text)
      free(text);

    ippDelete(event);
    event = NULL;
  }

 /*
  * We only get here when idle or error...
  */

  ippDelete(event);

  if (http)
  {
    unlink(filename);
    httpClose(http);
  }

  return (exit_status);
}
Example #27
0
int main(void)
{
	RTPSession sess;
	int portbase;
	unsigned long destip;
	int destport;
	char ipstr[256];
	int status;
	char dummybuffer[1024];
	struct timeval rttprev = {0,0},rtt,tv;
	int sock1,sock2;
	bool done;
	fd_set fdset;
	
        /*
           First, we'll ask for the necessary information
        */
		
	printf("Enter the local portbase\n");
	scanf("%d",&portbase);
	printf("\n");
	
	printf("Enter the destination IP address\n");
	scanf("%s",ipstr);
	destip = inet_addr(ipstr);
	if (destip == INADDR_NONE)
	{
		printf("Bad IP address specified\n");
		return -1;
	}
	
	// The inet_addr function returns a value in network byte order, but
	// we need the IP address in host byte order, so we use a call to
	// ntohl
	destip = ntohl(destip);
	
	printf("Enter the destination port\n");
	scanf("%d",&destport);
	
	/*
	   Now, we'll create a RTP session, set the destination, send some
	   packets and poll for incoming data.
	*/
	
	status = sess.Create(portbase);	
	checkerror(status);

	/* Get the sockets, so we can use them in a 'select' call */
	
	sess.GetRTPSocket(&sock1);
	sess.GetRTCPSocket(&sock2);
	
	status = sess.AddDestination(destip,destport);
	checkerror(status);

	printf("Press return to quit...\n");
	
	done = false;
	while (!done)
	{
		/* Just send something */
		
		status = sess.SendPacket("1234567890",10,0,false,10);
		checkerror(status);
		
		/* Wait for incoming data, or wait just one second */
		
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		FD_ZERO(&fdset);
		FD_SET(sock1,&fdset);
		FD_SET(sock2,&fdset);
		FD_SET(0,&fdset); // check for keypress
			
		select(FD_SETSIZE,&fdset,NULL,NULL,&tv);
		if (FD_ISSET(0,&fdset))
			done = true;
		
		/* poll for incoming data */
		
		status = sess.PollData();
		
		/* check incoming packets */
		
		if (sess.GotoFirstSourceWithData())
		{
			do
			{
				RTPSourceData *srcdat;
				
				srcdat = sess.GetCurrentSourceInfo();
				srcdat->FlushPackets(); // we don't need the actual data
				
				rtt = srcdat->INF_GetRoundTripTime();
				if (rtt.tv_sec != 0 || rtt.tv_usec != 0)
				{
					if ((rtt.tv_sec != rttprev.tv_sec) || (rtt.tv_usec != rttprev.tv_usec))
					{
						double t;
					
						t = (double)rtt.tv_sec;
						t += ((double)rtt.tv_usec)/1000000.0;
						t *= 1000.0; // we want milliseconds;
						printf("rtt: %f ms\n",(float)t);
						rttprev = rtt;
					}
				}
			} while (sess.GotoNextSourceWithData());
		}
	}
	
	return 0;
}
Example #28
0
/*--------------------------------------------------------------------------
**  Purpose:        Check for network status.
**
**  Parameters:     Name        Description.
**
**  Returns:        Nothing.
**
**------------------------------------------------------------------------*/
void npuNetCheckStatus(void)
    {
    struct timeval timeout;
    int readySockets = 0;
    Tcb *tp;

    timeout.tv_sec = 0;
    timeout.tv_usec = 0;

    while (pollIndex < npuNetTelnetConns)
        {
        tp = npuTcbs + pollIndex++;

        if (tp->state == StTermIdle)
            {
            continue;
            }

        /*
        **  Handle transparent input timeout.
        */
        if (tp->xInputTimerRunning && (cycles - tp->xStartCycle) >= Ms200)
            {
            npuAsyncFlushUplineTransparent(tp);
            }

        /*
        **  Handle network traffic.
        */
        FD_ZERO(&readFds);
        FD_ZERO(&writeFds);
        FD_SET(tp->connFd, &readFds);
        FD_SET(tp->connFd, &writeFds);
        readySockets = select(tp->connFd + 1, &readFds, &writeFds, NULL, &timeout);
        if (readySockets <= 0)
            {
            continue;
            }

        if (npuBipQueueNotEmpty(&tp->outputQ) && FD_ISSET(tp->connFd, &writeFds))
            {
            /*
            **  Send data if any is pending.
            */
            npuNetTryOutput(tp);
            }

        if (FD_ISSET(tp->connFd, &readFds))
            {
            /*
            **  Receive a block of data.
            */
            tp->inputCount = recv(tp->connFd, tp->inputData, sizeof(tp->inputData), 0);
            if (tp->inputCount <= 0)
                {
                /*
                **  Received disconnect - close socket.
                */
            #if defined(_WIN32)
                closesocket(tp->connFd);
            #else
                close(tp->connFd);
            #endif

                npuLogMessage("npuNet: Connection dropped on port %d\n", tp->portNumber);

                /*
                **  Notify SVM.
                */
                npuSvmDiscRequestTerminal(tp);
                }
            else if (tp->state == StTermHostConnected)
                {
                /*
                **  Hand up to the ASYNC TIP.
                */
                npuAsyncProcessUplineData(tp);
                }

            /*
            **  The following return ensures that we resume with polling the next
            **  connection in sequence otherwise low-numbered connections would get
            **  preferential treatment.
            */
            return;
            }
        }

    pollIndex = 0;
    }
Example #29
0
void gw_im_listener(void *arg)
{
    fd_set in_pipes;
    
    int    i,j;
    int    host_id;    
    int    greater, rc, rcm;
    int    num_mads;
    
    char   c;
    char   info[GW_IM_MAX_INFO];
    char   s_host_id[GW_IM_MAX_HOST_ID];
    char   result[GW_IM_MAX_RESULT];
    char   action[GW_IM_MAX_ACTION];
    char   str[GW_IM_MAX_STRING];    
    
    gw_host_t *   host;
    gw_im_mad_t * im_mad;
    
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
        
    while (1)
    {
        greater = gw_im_set_pipes (&in_pipes, &num_mads);
        
        select(greater+1, &in_pipes, NULL, NULL, NULL);

        for (i=0; i<=greater; i++)
        {            
            if ( FD_ISSET(i, &in_pipes) )
            {         
                im_mad = gw_im_get_mad_by_fd(i);
                
                if ( im_mad == NULL )
                    continue;
                
                j = 0;

                do
                {
                    rc = read(i, (void *) &c, sizeof(char));
                    str[j++] = c;    
                }
                while ((rc > 0) && (c != '\n') && (j < (GW_IM_MAX_STRING-1)));
                
                str[j] = '\0';

                if (rc <= 0)
                {
                    gw_log_print("IM",'W',"Error reading MAD (%s) message\n",
                            im_mad->name);

                    rcm = gw_im_mad_reload (im_mad);
                    
                    if ( rcm == 0 )
                        gw_log_print("IM",'I',"MAD (%s) successfully reloaded\n",
                            im_mad->name);
                    else
                    {
                        gw_log_print("IM",'E',"Error reloading IM MAD (%s)\n",
                            im_mad->name);
                            
                        im_mad->mad_im_pipe = -1;
                        
                        if ( num_mads == 1 )
                        {
                            gw_log_print("IM",'E',"GridWay needs to be restarted (no IM MADs left)!\n");                            
                            return;
                        }
                    }                            
                                                
                    continue;
                    
                }
                                    
                info[0] = '\0';

                rc = sscanf(str,"%" GW2STR(GW_IM_MAX_ACTION)"s %"
                            GW2STR(GW_IM_MAX_HOST_ID)"s %"
                            GW2STR(GW_IM_MAX_RESULT)"s %"
                            GW2STR(GW_IM_MAX_INFO) "[^\n]", 
                            action, 
                            s_host_id, 
                            result, 
                            info);
        
#ifdef GWIMDEBUG
                gw_log_print("IM",'D',"MAD (%s) message %s %s %s %s (info length=%d).\n",
                        im_mad->name, 
                        action, 
                        s_host_id, 
                        result,
                        info, 
                        strlen(info));
#endif

                if ( rc < 3 )
                {
                    gw_log_print("IM",'E',"Wrong field number in MAD (%s) message: %s.\n",
                            im_mad->name, str);
                    continue;
                }
                

                if (s_host_id[0] != '-')
                {
                    host_id = atoi(s_host_id);                    
                    
                    host = gw_host_pool_get_host (host_id, GW_FALSE);

                    if (host == NULL)
                    {
                        gw_log_print("IM",'E',"Message %s for host %d (does not exist) from MAD (%s).\n",
                                im_mad->name, action, host_id);
                        continue;
                    }
                }
                else
                {
                    host_id = -1;
                }

                if (strcmp(action, "DISCOVER") == 0)
                {
                    pthread_mutex_lock(&(gw_im.mutex));

                    gw_im.active_queries--;

#ifdef GWIMDEBUG
                    gw_log_print("IM",'D',"Discovery action done, %i active queries.\n", gw_im.active_queries);
#endif

                    pthread_mutex_unlock(&(gw_im.mutex));

                    if (strcmp(result, "SUCCESS") == 0)
                    {
                        if (strlen(info) > 0)
                        {
                            
                            gw_log_print("IM",'I',"Hosts discovered by MAD (%s): %s\n",
                                    im_mad->name, info);
                                    
                            gw_host_pool_update(info,
                                    im_mad->em_mad_name,
                                    im_mad->tm_mad_name,
                                    im_mad->name);
                            
#ifdef GWIMDEBUG
                            gw_host_pool_print(stdout);
#endif
                        }
                        else
                        {
                            gw_log_print("IM",'I',"No hosts discovered by MAD (%s)\n",
                                    im_mad->name);
                        }
                    }
                    else
                    {
                        gw_log_print("IM",'E',"DISCOVER error in MAD (%s): %s\n",
                                im_mad->name, info);
                    }

                    im_mad->state = GW_IM_MAD_STATE_IDLE;
                }
                else if (strcmp(action, "MONITOR") == 0)
                {
                    pthread_mutex_lock(&(gw_im.mutex));

                    gw_im.active_queries--;

#ifdef GWIMDEBUG
                    gw_log_print("IM",'D',"Monitoring action done, %i active queries.\n", gw_im.active_queries);
#endif

                    pthread_mutex_unlock(&(gw_im.mutex));

                    if (strcmp(result, "SUCCESS") == 0)
                    {
                        gw_host_update(host_id, info);

#ifdef GWIMDEBUG
                        gw_log_print("IM",'D',"Host %i successfully monitored.\n",
                                host_id);
#endif
                    }
                    else
                    {
                        gw_log_print("IM",'E',"MONITOR error in MAD (%s): %s\n",
                                im_mad->name, info);
                                
                        gw_host_clear_dynamic_info(host_id);
                    }
                }
            }
        }
    }
}
Example #30
0
//
//  function: tunnel_server_handler
//      opne a service port and process the service request from devices
//      parameters
//          service port number
//      return
//          0       success
//          other   fail
//
void *tunnel_server_handler(void *pdata)
{
    fd_set readfds, writefds, rfds, wfds;
    int nfds=-1,servfd=-1, sd=-1, ret=-1;
    struct timeval tv;
    struct sockaddr_in clientaddr; /* client addr */
    int optval; /* service socket */
    unsigned int next_time, current_time;
#ifdef _OPEN_SECURED_CONN
    SSL *ssl=NULL;
    int securefd = -1;
#endif                
    //
    // tunnel control block init
    //
    if (tunnel_ctrl_init()<0)
  	{
  		p2p_log_msg( "initial tunnel control block fail!");
        goto end_tunnel_server_handler;
  	} 
  	
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    
    // wait mone secure connection
    servfd = do_bind_service_port(service_port);
    if (servfd>=0)
    {    
        FD_SET(servfd, &readfds);
        nfds = (servfd>nfds?servfd:nfds);
    }
    else
       goto end_tunnel_server_handler;     
       
#ifdef _OPEN_SECURED_CONN
    // wait mone secure connection
    securefd = do_bind_service_port(secure_service_port);
    if (securefd>=0)
    {    
        FD_SET(securefd, &readfds);
        nfds = (securefd>nfds?securefd:nfds);
    }
    else
       goto end_tunnel_server_handler;
#endif    
     	
    //
    // report to SC that service start
    //
    do_service_start("tunnel server start");
    
    //
    // main loop: wait for a connection request
    //
    current_time = get_time_milisec();
    next_time  = current_time + 10000;   // next seconds
    while (tunnel_server_on) 
    {
        current_time = get_time_milisec();
        if (current_time > next_time)
        {    
            // if timer expired, do report to SC
            do_service_report();
            next_time = current_time + 10000;   // 10 seconds
        }
        memcpy(&rfds,&readfds,sizeof(fd_set));
        memcpy(&wfds,&writefds,sizeof(fd_set));
        // reset timeout value
        tv.tv_sec = 1;  // 1 seconds
        tv.tv_usec = 0;
        if((ret=select(nfds+1, &rfds, &wfds, NULL, &tv)) == -1)
        {
            p2p_log_msg( "Server-select() error lol!");
            goto end_tunnel_server_handler;
        }
#ifdef _OPEN_SECURED_CONN
        if (FD_ISSET(securefd, &rfds))
        {
            socklen_t clientlen = sizeof(clientaddr);
            sd = ssl_server_accept(securefd,&ssl);
            if (sd >= 0)
            {   
            	getpeername(sd, (struct sockaddr*)&clientaddr, &clientlen);
                p2p_log_msg("new secure connection from %s\n",inet_ntoa (clientaddr.sin_addr));
                ret = new_device_tunnel(sd, &clientaddr, ssl);
                if (ret<0)
                {
                    p2p_log_msg("reject secure connection from %s\n",inet_ntoa (clientaddr.sin_addr));
                    ssl_server_close(ssl);
                }
            }
            else     
                p2p_log_msg("ERROR on accept");
        }    
#endif        
        // new conenction incoming?
        if (FD_ISSET(servfd, &rfds))
        {
            // 
            //  accept: wait for a connection request 
            //
            socklen_t clientlen = sizeof(clientaddr);
            sd = accept(servfd, (struct sockaddr *) &clientaddr, &clientlen);
            if (sd >= 0)
            {   
            	getpeername(sd, (struct sockaddr*)&clientaddr, &clientlen);
                p2p_log_msg("new connection from %s\n",inet_ntoa (clientaddr.sin_addr));
#ifdef _OPEN_SECURED_CONN                
                ret = new_device_tunnel(sd, &clientaddr, NULL);
#else                
                ret = new_device_tunnel(sd, &clientaddr);
#endif                
                if (ret<0)
                {
                    p2p_log_msg("reject connection from %s\n",inet_ntoa (clientaddr.sin_addr));
                    close(sd);
                }    
            }    
            else     
                p2p_log_msg("ERROR on accept");
        }
    }   // end of while
    
end_tunnel_server_handler:  
	// close all existing tunnel
	if (servfd>0)
	    close(servfd);
#ifdef _OPEN_SECURED_CONN
    if (securefd>=0)
	    close(securefd);
#endif	    
	do_service_exit("tunnel server exit");
	tunnel_ctrl_free();
    tunnel_server_on = 0;
    return NULL;
}   // endo fo tunnel server