示例#1
0
// Main server process that continuously runs until cntrl-c
int main(int argc, char* argv[])
{
  pid_t spid, term_pid; /* pid_t is typedef for Linux process ID */ 
  int chld_status;
  bool forever = true;

  if (argc < 2)
  {
    printf("No port specified\n");
    return (-1);
  }

  /* create a "welcoming" socket at the specified port */
  welcome_socket = ServerSocket_new(atoi(argv[1]));
  if (welcome_socket < 0)
  {
    printf("Failed new server socket\n");
    return (-1);
  }

  /* The daemon infinite loop begins here; terminate with external action*/
  while (forever)
  {
    /* accept an incoming client connection; blocks the
     * process until a connection attempt by a client.
     * creates a new data transfer socket.
     */
    connect_socket = ServerSocket_accept(welcome_socket);
    if (connect_socket < 0)
    {
      printf("Failed accept on server socket\n");
      exit (-1);
    }
    spid = fork();  /* create child == service process */
    if (spid == -1) 
    {
      perror("fork"); 
      exit (-1);
    }
    if (spid == 0) 
    {/* code for the service process */
      ForkExecuteRedirect_service();
      Socket_close(connect_socket);
      exit (0);
    } /* end service process */
    else /* daemon process closes its connect socket */
    {
      Socket_close(connect_socket);
      /* reap a zombie every time through the loop, avoid blocking*/
      term_pid = waitpid(-1, &chld_status, WNOHANG);
    }
  } /* end of infinite loop for daemon process */
}
示例#2
0
void MQTTClient_closeSession(Clients* client)
{
	FUNC_ENTRY;
	client->good = 0;
	client->ping_outstanding = 0;
	if (client->net.socket > 0)
	{
		if (client->connected)
			MQTTPacket_send_disconnect(&client->net, client->clientID);
		Thread_lock_mutex(socket_mutex);
#if defined(OPENSSL)
		SSLSocket_close(&client->net);
#endif
		Socket_close(client->net.socket);
		Thread_unlock_mutex(socket_mutex);
		client->net.socket = 0;
#if defined(OPENSSL)
		client->net.ssl = NULL;
#endif
	}
	client->connected = 0;
	client->connect_state = 0;

	if (client->cleansession)
		MQTTClient_cleanSession(client);
	FUNC_EXIT;
}
示例#3
0
void MQTTProtocol_closeSession(Clients* client, int sendwill)
{
	FUNC_ENTRY;
	client->good = 0;
	if (client->net.socket > 0)
	{
		if (client->connected || client->connect_state)
		{
			MQTTPacket_send_disconnect(&client->net, client->clientID);
			client->connected = 0;
			client->connect_state = 0;
		}
#if defined(OPENSSL)
		SSLSocket_close(&client->net);
#endif
		Socket_close(client->net.socket);
		client->net.socket = 0;
#if defined(OPENSSL)
		client->net.ssl = NULL;
#endif
	}

	if (client->cleansession)
		MQTTClient_cleanSession(client);
	FUNC_EXIT;
}
示例#4
0
// Sets up the service, ForkExecuteRedirect helper actually execs code
void ForkExecuteRedirect_service(void)
{
  int i, c, rc;
  int count = 0;
  bool forever = true;

  char input [INPUT_SIZE_MAX] = "";
  int numArguments = 0;
  pid_t childPID;
  char** arguments = NULL;
  int input_index = 0;

  /* will not use the server socket */
  Socket_close(welcome_socket);

  while (forever)  /* actually, until EOF on connect socket */
  {
    /* get a null-terminated string from the client on the data
     * transfer socket up to the maximim input line size.  Continue 
     * getting strings from the client until EOF on the socket.
     */ 
    for (i = 0; i < MAX_LINE; i++)
    {
      c = Socket_getc(connect_socket);
      if (c == EOF)
      {
        printf("Socket_getc EOF or error\n"); 
        return; /* assume socket EOF ends service for this client */           
      }
      else
      {

        if (c == '\n'){ // command entered
          input[input_index] = ' ';
          input[input_index + 1] = '\0'; // null-terminates string
          //printf("input: [%s]\n", input);
          arguments = getArgs(input, &numArguments);
          ForkExecuteRedirect_helper(numArguments, arguments);
        }

        else{ // command not entered, just continue filling input buffer
          if (input_index <= INPUT_SIZE_MAX){
            input[input_index] = c;
            input[input_index + 1] = '\0';
            input_index++;
          }
          else // if input size too large
            printf("max input size reached, no more input will be processed\n");
        }

      }
    }
  } /* end while loop of the service process */
  return;
}
示例#5
0
void check_put(int rc, void *p){

  Socket *s = p;
  Socket connect_socket = *s;
  if (rc == EOF){
    
    printf("Socket_putc EOF or error\n");
    Socket_close(connect_socket);
    exit (ERROR);  /* assume socket problem is fatal*/
  }
}
示例#6
0
文件: SRL_ftp.c 项目: dcblake/SMP
/*
 * Ftp_Connect - connect to remote server
 *
 * return 1 if connected, 0 if not
 */
int Ftp_Connect(const char *host, int port, netbuf **nControl)
{
	int		socket_d = 0;
    netbuf	*ctrl;

    socket_d = Socket_Connect(host, port);
	if (socket_d > 0)
	{
		// allocate and fill in netbuf structure

		ctrl = calloc(1,sizeof(netbuf));
		if (ctrl == NULL)
		{

			Socket_close(socket_d);
			return 0;
		}
		ctrl->buf = malloc(FTP_BUFSIZ);
		if (ctrl->buf == NULL)
		{

			Socket_close(socket_d);
			free(ctrl);
			return 0;
		}
		ctrl->handle = socket_d;
		ctrl->dir = FTP_CONTROL;
		if (readresp('2', ctrl) == 0)
		{

			Socket_close(socket_d);
			free(ctrl->buf);
			free(ctrl);
			return 0;
		}
		*nControl = ctrl;
		return 1;
	}
	else
		return 0;
}
示例#7
0
文件: SRL_ftp.c 项目: dcblake/SMP
/*
 * Ftp_Quit - disconnect from remote
 *
 * return 1 if successful, 0 otherwise
 */
 void Ftp_Quit(netbuf *nControl)
{
    if (nControl->dir != FTP_CONTROL)
		return;
    Ftp_Send("QUIT",'2',nControl);
    Socket_close(nControl->handle);
    free(nControl->buf);
    free(nControl);
#ifdef WIN32
	// Clean up for windows
		 WSACleanup ();
#endif
}
示例#8
0
/*==============================================================================
* Name	 :	void Client_stop_cb(struct ev_loop* lp, ev_timer* wt, int ev)
* Abstr	 :	Time to close the connection and start the re-connect timer
* Params :	struct ev_loop* lp: inner event loop
*			ev_timer* 		wt: timer watcher
*			int 			ev: specific event
* Return :	
* Modify :	
*=============================================================================*/
static void Client_stop_cb(struct ev_loop* lp, ev_timer* wt, int ev)
{	
	CONN_INFO*			conn;	/* connection with servant server */
	
	conn = container_of(wt, CONN_INFO, t_wt);

	/* free socket resource */
	Socket_shutdown(&conn->fd, &conn->name[0]);
	Socket_close   (&conn->fd, &conn->name[0]);

	/* prepare reconnect msg */
	memset(&conn->s_buf[0], 0x00, SEND_LEN_MAX);
	Client_start_prepare(conn);

	/* re-start the connection with servant server */
	Client_switch_to_start(conn);
}
示例#9
0
static void
connectHostNext(ConnectState *connectState) {
	Socket *sock;

	while (connectState->infoPtr != NULL) {
		sock = tryConnectHostNext(connectState);

		if (sock != Socket_noSocket) {
			// Connection succeeded or connection in progress
			connectState->nd =
					NetDescriptor_new(sock, (void *) connectState);
			if (connectState->nd == NULL) {
				ConnectError error;
				int savedErrno = errno;

				log_add(log_Error, "NetDescriptor_new() failed: %s.\n",
						strerror(errno));
				Socket_close(sock);
				freeaddrinfo(connectState->info);
				connectState->info = NULL;
				connectState->infoPtr = NULL;
				connectState->state = Connect_closed;
				error.state = Connect_connecting;
				error.err = savedErrno;
				doConnectErrorCallback(connectState, &error);
				return;
			}

			NetDescriptor_setWriteCallback(connectState->nd, connectCallback);
			setConnectTimeout(connectState);
			return;
		}

		connectState->infoPtr = connectState->infoPtr->ai_next;
	}

	// Connect failed to all addresses.

	if (connectState->flags.retryDelayMs == Connect_noRetry) {
		connectHostReportAllFailed(connectState);
		return;
	}

	setConnectRetryAlarm(connectState);
}
示例#10
0
static
int send_msg( char *dest_addr, char *return_addr, NodeMessage *msg )
{
    int dest_port, buflen = SENDBUF_LEN;
    char *colon, buf[SENDBUF_LEN], dest_host[16];
    int sock;

    colon = strchr( (const char*)dest_addr, ':' );
    if (colon == NULL) {
        Dbg_printf( NODE, ERROR, "send_msg, ':' not found in the dest_addr=%s\n", dest_addr );
        return -1;
    }
    
    memcpy( dest_host, dest_addr, sizeof(char) * (colon - dest_addr) );
    dest_host[colon - dest_addr] = '\0';
    dest_port = atoi( colon + 1 );

    if ((sock = Socket_create()) < 0 ) {
        Dbg_printf( NODE, ERROR, "send_msg, socket creation failed\n" );
        return -1;
    }

    node_set_return_addr( msg, return_addr );

    if (Socket_connect( sock, dest_host, dest_port ) < 0) {
        Dbg_printf( NODE, ERROR, "send_msg, socket connect failed\n" );
        return -1;
    }

    if (node_stringify_msg( msg, buf, &buflen ) < 0 ) {
        Dbg_printf( NODE, ERROR, "send_msg, msg stringify failed\n" );
        return -1;
    }

    Socket_send_data( sock, buf, buflen );

    Socket_close( sock );

    Dbg_printf( NODE, API, "%s message sent to %s\n", node_msgid2str( msg->msgid ), dest_addr );

    return 0;
}
示例#11
0
void MQTTProtocol_closeSession(Clients* client, int sendwill)
{
	FUNC_ENTRY;
	client->good = 0;
	if (client->socket > 0)
	{
		if (client->connected || client->connect_state)
		{
			MQTTPacket_send_disconnect(client->socket, client->clientID);
			client->connected = 0;
			client->connect_state = 0;
		}
		Socket_close(client->socket);
		client->socket = 0;
	}

	if (client->cleansession)
		MQTTClient_cleanSession(client);
	FUNC_EXIT;
}
示例#12
0
文件: IoSocket.c 项目: BMeph/io
IoObject *IoSocket_close(IoSocket *self, IoObject *locals, IoMessage *m)
{
	//doc Socket close Closes the socket and returns self. Returns nil on error.
	
	if (Socket_close(SOCKET(self)))
	{
		IoSocket_rawSetupEvents(self, locals, m);
		return self;
	}
	else
	{
		if (Socket_closeFailed())
		{
			return SOCKETERROR("Failed to close socket");
		}
		else
		{
			return IONIL(self);
		}
	}
}
示例#13
0
int main(int argc, char* argv[])
{
    int i, c, rc, fc;
    int count = 0;

    char line_data[MAX_LINE];

    /* variable to hold socket descriptor */
    Socket connect_socket;

    if (argc < 3)
    {
        printf("No host and port\n");
        return (-1);
    }

    /* connect to the server at the specified host and port;
     * blocks the process until the connection is accepted
     * by the server; creates a new data transfer socket.
     */
    connect_socket = Socket_new(argv[1], atoi(argv[2]));
    if (connect_socket < 0)
    {
        printf("Failed to connect to server\n");
        return (-1);
    }

    printf("%% "); // print initial prompt

    /* get a string from stdin up to and including
     * a newline or to the maximim input line size.
     * Continue getting strings from stdin until EOF.
     */



    while ((fgets(line_data, sizeof(line_data), stdin) != NULL))
    {
        count = strlen(line_data) + 1; /* count includes '\0' */

        /* send the characters of the input line to the server
         * using the data transfer socket.
         */
        for (i = 0; i < count; i++)
        {
            c = line_data[i];
            rc = Socket_putc(c, connect_socket);
            // if (rc == EOF)
            // {
            //   printf("Socket_putc EOF or error\n");
            //   Socket_close(connect_socket);
            //      exit (-1);  /* assume socket problem is fatal, end client */
            // }
        }


        /* receive the converted characters for the string from
         * the server using the data transfer socket.
         */
        printf("boutta receive\n");
        while (1) {
            fc = Socket_getc(connect_socket);
            printf("%c", fc);
            if (fc == '\0') {
                break;
            }
        }

        printf("%% "); // print prompt for next command

    } /* end of while loop; at EOF */

    Socket_close(connect_socket);
    exit(0);
}
示例#14
0
int MQTTSProtocol_handleConnects(void* pack, int sock, char* clientAddr, Clients* client, uint8_t* wirelessNodeId , uint8_t wirelessNodeIdLen)
{
	MQTTS_Connect* connect = (MQTTS_Connect*)pack;
	Listener* list = NULL;
	int terminate = 0;
	Node* elem = NULL;
	int rc = 0;
	int existingClient = 0;

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 39, NULL, sock, clientAddr, client ? client->clientID : "", connect->flags.cleanSession);

	if (bstate->clientid_prefixes->count > 0 &&
		!ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare))
	{
		Log(LOG_WARNING, 31, NULL, connect->clientID);
		terminate = 1;
	}
	else
	{
		list = Socket_getParentListener(sock);
		if (list->max_connections > -1 &&
				list->connections->count > list->max_connections)
		{
			/* TODO: why is this commented out? delete if not needed
			//MQTTPacket_send_connack(3, sock);
			*/
			Log(LOG_WARNING, 141, NULL, connect->clientID, list->max_connections, list->port);
			terminate = 1;

		}
		else if (connect->protocolID != 1)
		{
			Log(LOG_WARNING, 32, NULL, "MQTT-S", connect->protocolID);
			/* TODO: why is this commented out? delete if not needed
			//MQTTPacket_send_connack(1, sock);
			 */
			terminate = 1;
		}
	}

	if (terminate)
	{
		/*TODO: process the terminate*/
		MQTTSPacket_free_packet(pack);
		goto exit;
	}

	if (client != NULL && !strcmp(client->clientID, connect->clientID))
	{
		/* Connect for a new client id on a used addr
		 * TODO: clean out 'old' Client (that may be 'connected')
		 */
	}

	elem = TreeFindIndex(bstate->mqtts_clients, connect->clientID, 1);
	if (elem == NULL)
	{
		client = TreeRemoveKey(bstate->disconnected_mqtts_clients, connect->clientID);
		if (client == NULL) /* this is a totally new connection */
		{
			/* Brand new client connection */
			int i;
		
			client = malloc(sizeof(Clients));
			memset(client, '\0', sizeof(Clients));
			client->protocol = PROTOCOL_MQTTS;
			client->outboundMsgs = ListInitialize();
			client->inboundMsgs = ListInitialize();
			for (i = 0; i < PRIORITY_MAX; ++i)
				client->queuedMsgs[i] = ListInitialize();
			client->registrations = ListInitialize();
			client->noLocal = 0; /* (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0; */
			client->clientID = connect->clientID;
			connect->clientID = NULL; /* don't want to free this space as it is being used in the clients tree below */
			// Set Wireless Node ID if exists
			if ( wirelessNodeId == NULL)
			{
				client->wirelessNodeId = NULL ;
				client->wirelessNodeIdLen = 0 ;
			}
			else
			{
				client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ;
				memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ;
				client->wirelessNodeIdLen = wirelessNodeIdLen ;
			}
		} // // client == NULL
		else /* there is an existing disconnected client */
		{
			/* Reconnect of a disconnected client */
			free(client->addr);
			client->connect_state = 0;
			client->connected = 0; /* Do not connect until we know the connack has been sent */

			// Delete Wireless Node ID if exists in existing client
			if ( wirelessNodeId == NULL)
			{
				if ( client->wirelessNodeId != NULL)
					free( client->wirelessNodeId )  ;
				client->wirelessNodeId = NULL ;
				client->wirelessNodeIdLen = 0 ;
			}
			else
			// Replace existing Wireless Node ID with value from current connect packet
			{
				if ( client->wirelessNodeId != NULL)
					free ( client->wirelessNodeId )  ;
				client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ;
				memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ;
				client->wirelessNodeIdLen = wirelessNodeIdLen ;
			}
		} // client != NULL
		client->good = 1; /* good is set to 0 in disconnect, so we need to reset it here */
		client->keepAliveInterval = connect->keepAlive;
		client->cleansession = connect->flags.cleanSession;
		client->socket = sock;
		client->addr = malloc(strlen(clientAddr)+1);
		strcpy(client->addr, clientAddr);
		TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));

		if (client->cleansession)
			MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */

		if (connect->flags.will)
		{
			client->connect_state = 1;
			rc = MQTTSPacket_send_willTopicReq(client);
		}
		else
		{
			client->connected = 1;
			rc = MQTTSPacket_send_connack(client, 0); /* send response */
		}
	}
	else
	{
		/* Reconnect of a connected client */
		client = (Clients*)(elem->content);
		if (client->connected)
		{
			Log(LOG_INFO, 34, NULL, connect->clientID, clientAddr);
			if (client->socket != sock)
				Socket_close(client->socket);
		}
		client->socket = sock;
		client->connected = 0; /* Do not connect until we know the connack has been sent */
		client->connect_state = 0;

		// Delete Wireless Node ID if exists in existing client
		if ( wirelessNodeId == NULL)
		{
			if ( client->wirelessNodeId != NULL)
				free( client->wirelessNodeId )  ;
			client->wirelessNodeId = NULL ;
			client->wirelessNodeIdLen = 0 ;
		}
		else
		// Replace existing Wireless Node ID with value from current connect packet
		{
			if ( client->wirelessNodeId != NULL)
				free ( client->wirelessNodeId )  ;
			client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ;
			memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ;
			client->wirelessNodeIdLen = wirelessNodeIdLen ;
		}

		client->good = 1;
		if (client->addr != NULL)
			free(client->addr);
		client->addr = malloc(strlen(clientAddr)+1);
		strcpy(client->addr, clientAddr);

		client->cleansession = connect->flags.cleanSession;
		if (client->cleansession)
		{
			int i;
			MQTTProtocol_removeAllSubscriptions(client->clientID);
			/* empty pending message lists */
			MQTTProtocol_emptyMessageList(client->outboundMsgs);
			MQTTProtocol_emptyMessageList(client->inboundMsgs);
			for (i = 0; i < PRIORITY_MAX; ++i)
				MQTTProtocol_emptyMessageList(client->queuedMsgs[i]);
			MQTTProtocol_clearWill(client);
		}
		/* registrations are always cleared */
		MQTTSProtocol_emptyRegistrationList(client->registrations);
		
		/* have to remove and re-add client so it is in the right order for new socket */
		if (client->socket != sock)
		{
			TreeRemoveNodeIndex(bstate->mqtts_clients, elem, 1);
			TreeRemoveKeyIndex(bstate->mqtts_clients, &client->socket, 0);
			client->socket = sock;
			TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
		}

		client->keepAliveInterval = connect->keepAlive;
		client->pendingRegistration = NULL;
#if !defined(NO_BRIDGE)
		client->pendingSubscription = NULL;
#endif

		if (connect->flags.will)
		{
			client->connect_state = 1;
			rc = MQTTSPacket_send_willTopicReq(client);
		}
		else
		{
			client->connected = 1;
			rc = MQTTSPacket_send_connack(client,0); /* send response */
		}
	}
	
	if (existingClient)
		MQTTProtocol_processQueued(client);

	Log(LOG_INFO, 0, "Client connected to udp port %d from %s (%s)", list->port, client->clientID, clientAddr);

	MQTTSPacket_free_packet(pack);
	time( &(client->lastContact) );
exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
示例#15
0
/**
 * Close any active session for a client and clean up.
 * @param client the client to clean up
 * @param send_will flag to indicate whether a will messsage should be sent if it has been set
 */
void MQTTProtocol_closeSession(Clients* client, int send_will)
{
	FUNC_ENTRY;
	client->good = 0;
	if (in_MQTTPacket_Factory == client->socket || client->closing)
		goto exit;
	client->closing = 1;
	if (client->socket > 0)
	{
		if (client->connected)
		{
			if (client->outbound && client->will)
			{
				Publish pub;
				pub.payload = "0";
				pub.payloadlen = 1;
				pub.topic = client->will->topic;
#if defined(MQTTS)
				if (client->protocol == PROTOCOL_MQTTS)
					MQTTSProtocol_startPublishCommon(client, &pub, 0,0,1);
				if (client->protocol == PROTOCOL_MQTTS_DTLS)
					MQTTSProtocol_startPublishCommon(client, &pub, 0,0,1);
					//TODO LW
				else
#endif
					MQTTPacket_send_publish(&pub, 0, 0, 1, client->socket, client->clientID);
				MQTTProtocol_sys_publish(client->will->topic, "0");
			}
#if defined(MQTTS)
			if (client->protocol == PROTOCOL_MQTTS_MULTICAST)
				;
			else if (client->protocol == PROTOCOL_MQTTS)
				MQTTSPacket_send_disconnect(client, 0);
			else if (client->protocol == PROTOCOL_MQTTS_DTLS)
				MQTTSPacket_send_disconnect(client, 0);
			else
#endif
			if (client->outbound)
				MQTTPacket_send_disconnect(client->socket, client->clientID);
		}

		if (ListFindItem(&(state.pending_writes), &(client->socket), intcompare))
		{
			pending_write* pw = (pending_write*)(state.pending_writes.current->content);
			MQTTProtocol_removePublication(pw->p);
			ListRemove(&(state.pending_writes), pw);
		}

#if defined(MQTTS)
		if (client->protocol == PROTOCOL_MQTT || client->outbound == 1)
		{
			if (client->protocol == PROTOCOL_MQTTS_MULTICAST)
				Socket_close_only(client->socket);
			else
#endif
				Socket_close(client->socket);
#if defined(MQTTS)
		}
#endif
	}
	if (client->connected || client->connect_state)
	{
		client->connected = 0;
		client->connect_state = 0;
	}
	if (client->outbound == 0 && client->will != NULL && send_will)
	{
		Publish publish;
		publish.payload = client->will->msg;
		publish.payloadlen = strlen(client->will->msg);
		publish.topic = client->will->topic;
		publish.header.bits.qos = client->will->qos;
		publish.header.bits.retain = client->will->retained;
		Protocol_processPublication(&publish, client->clientID);
	}
#if defined(MQTTS)
	if (client->protocol == PROTOCOL_MQTTS)
		MQTTSProtocol_emptyRegistrationList(client->registrations);
	else if (client->protocol == PROTOCOL_MQTTS_DTLS)
		MQTTSProtocol_emptyRegistrationList(client->registrations);
#endif
	if (client->cleansession)
	{
		if (client->outbound && ((BridgeConnections*)(client->bridge_context))->state != CONNECTION_DELETE)
		{ /* bridge outbound client structures are reused on reconnection */
			int i;
			MQTTProtocol_removeAllSubscriptions(client->clientID);
			MQTTProtocol_emptyMessageList(client->inboundMsgs);
			MQTTProtocol_emptyMessageList(client->outboundMsgs);
			for (i = 0; i < PRIORITY_MAX; ++i)
				MQTTProtocol_emptyMessageList(client->queuedMsgs[i]);
			client->msgID = 0;
		}
		else
		{
#if defined(MQTTS)
			if ((client->protocol == PROTOCOL_MQTTS && client->outbound == 0) || (client->protocol == PROTOCOL_MQTTS_DTLS && client->outbound == 0) || client->protocol == PROTOCOL_MQTTS_MULTICAST)
			{
				if (!TreeRemove(bstate->mqtts_clients, client) && !TreeRemove(bstate->disconnected_mqtts_clients, client))
					Log(LOG_ERROR, 39, NULL);
				else
					Log(TRACE_MAX, 2, NULL, client->clientID, client->socket);
			}
			else
			{
#endif
				if (!TreeRemove(bstate->clients, client) && !TreeRemove(bstate->disconnected_clients, client))
					Log(LOG_ERROR, 39, NULL);
				else
					Log(TRACE_MAX, 2, NULL, client->clientID, client->socket);
#if defined(MQTTS)
			}
#endif
			MQTTProtocol_freeClient(client);
		}
	}
	else
	{
		int i;
		for (i = 0; i < PRIORITY_MAX; ++i)
			MQTTProtocol_removeQoS0Messages(client->queuedMsgs[i]);
#if defined(MQTTS)
		if ((client->protocol == PROTOCOL_MQTTS && client->outbound == 0)||(client->protocol == PROTOCOL_MQTTS_DTLS && client->outbound == 0))
		{
			if (TreeRemove(bstate->mqtts_clients, client))
			{
				client->socket = 0;
				TreeAdd(bstate->disconnected_mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
			}
		}
		else
		{
#endif
		if (TreeRemove(bstate->clients, client))
		{
			client->socket = 0;
			TreeAdd(bstate->disconnected_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
		}
#if defined(MQTTS)
		}
#endif
    	client->closing = 0;
	}

exit:
	FUNC_EXIT;
}
示例#16
0
/**
 * MQTT protocol timeslice for one packet and client - must not take too long!
 * @param sock the socket which is ready for the packet to be read from
 * @param client the client structure which corresponds to the socket
 */
void MQTTProtocol_timeslice(int sock, Clients* client)
{
	int error;
	MQTTPacket* pack;

	FUNC_ENTRY;

	Log(TRACE_MIN, -1, "%d %s About to read packet for peer address %s",
			sock, (client == NULL) ? "unknown" : client->clientID, Socket_getpeer(sock));
	in_MQTTPacket_Factory = sock;
	pack = MQTTPacket_Factory(sock, &error);
	in_MQTTPacket_Factory = -1;
	if (pack == NULL)
	{ /* there was an error on the socket, so clean it up */
		if (error == SOCKET_ERROR || error == BAD_MQTT_PACKET)
		{
			if (client != NULL)
			{
				client->good = 0; /* make sure we don't try and send messages to ourselves */
				if (error == SOCKET_ERROR)
					Log(LOG_WARNING, 18, NULL, client->clientID, sock, Socket_getpeer(sock));
				else
					Log(LOG_WARNING, 19, NULL, client->clientID, sock, Socket_getpeer(sock));
				MQTTProtocol_closeSession(client, 1);
			}
			else
			{
				if (error == SOCKET_ERROR)
					/* Don't do a Socket_getpeer in the case of SOCKET_ERROR -
					 * otherwise another SOCKET_ERROR will be hit  */
					Log(LOG_WARNING, 20, NULL, sock, "unknown");
				else
					Log(LOG_WARNING, 21, NULL, sock, Socket_getpeer(sock));
				Socket_close(sock);
			}
		}
	}
	else if (handle_packets[pack->header.bits.type] == NULL)
		Log(LOG_WARNING, 22, NULL, pack->header.bits.type, sock);
	else
	{
		if (client == NULL && pack->header.bits.type != CONNECT)
		{
			Log(LOG_WARNING, 23, NULL, sock, Socket_getpeer(sock), MQTTPacket_name(pack->header.bits.type));
			MQTTPacket_free_packet(pack);
			Socket_close(sock);
		}
		else
		{
			Node* elem = NULL;
			/* incoming publish at QoS 0 does not result in outgoing communication, so we don't want to count it as contact,
			   for PING processing on outbound connections */
			int update_time = (pack->header.bits.type == PUBLISH && pack->header.bits.qos == 0) ? 0 : 1;
			if (client && (update_time || (client->outbound == 0)))
				time(&(client->lastContact));
			if ((*handle_packets[pack->header.bits.type])(pack, sock, client) == SOCKET_ERROR)
			{
				/* the client could have been closed during handle_packet, so check to see if it's still in the client list */
				elem = TreeFind(bstate->clients, &sock);
				if (elem == NULL && client && client->clientID)
					elem = TreeFind(bstate->disconnected_clients, client->clientID);
				if (elem != NULL)
				{
					client = (Clients*)(elem->content);
					client->good = 0; /* make sure we don't try and send messages to ourselves */
					Log(LOG_WARNING, 18, NULL, client->clientID, sock, Socket_getpeer(sock));
					MQTTProtocol_closeSession(client, 1);
				}
				else
				{
					Log(LOG_WARNING, 20, NULL, sock, Socket_getpeer(sock));
					Socket_close(sock);
				}
			}
		}
	}
	/*MQTTProtocol_housekeeping(); move to Protocol_timeslice*/
	FUNC_EXIT;
}
示例#17
0
void  shell_service(void){
  
  int i = 0, c, character, rc, no_error;
  //MAX_LINE is the longest the stdin buffer can be, so we won't overflow it
  char line_data[MAX_LINE];
  pid_t cpid, term_pid; /* pid_t is typedef for Linux process ID */
  int chld_status;
  unsigned char new_line[MAX_LINE];
  unsigned char tmp_name[MAX_TMP];
  unsigned char id_str[MAX_TMP];
  char response[MAX_LINE];
  char temp[MAX_LINE];
  int id;

  /* variable names for file "handles" */
  FILE *tmpFP;
  FILE *fp;

  /* get the parent process ID and use it to create a file name for the
   * temporary file with the format "tmpxxxxx" where xxxxx is the ID
   */
  id = (int) getpid();
  sprintf(id_str, "%d", id);
  strcpy(tmp_name,"tmp");
  strcat(tmp_name, id_str);

  /* will not use the server socket */
  Socket_close(welcome_socket);
  
  while((c = Socket_getc(connect_socket)) != EOF){
    
    if(c != NEWLINE){
     
      line_data[i] = c;
      i ++;
    }
    else{
      
      line_data[i] = STRING_END;
      i++;

      //make sure the string is terminated
      if(i == MAX_LINE){
	line_data[MAX_LINE - 1] = STRING_END;
      }
      
      cpid = fork();  /* create child == service process */
      if (cpid == ERROR){
	
      	perror("fork");
	exit (ERROR);
      }
      if (cpid == NORMAL) {/* code for the service process */
	
	/* dynamically redirect stdout to the named temporary
	 * file open for writing
	 */
	fp = freopen(tmp_name, "w", stdout);
	
      	parse_input(line_data, &connect_socket);
      } /* end service process */
      else{
	
	i = 0;
	
	term_pid = waitpid(cpid, &chld_status, 0);
	if (term_pid == ERROR)
	  perror("waitpid");
	else{
	  
	  if (WIFEXITED(chld_status))
	    sprintf(response, "End of input: PID %d exited, status = %d\n", cpid, WEXITSTATUS(chld_status));
	  else
	    sprintf(response, "End of Input: PID %d did not exit normally\n", cpid);
	}
	
	if ((tmpFP = fopen (tmp_name, "r")) == NULL) {
	  
	  fprintf (stderr, "error opening tmp file\n");
	  exit (ERROR);
	}

	no_error = 0;
	while (!feof (tmpFP)) {
	  no_error = 1;
	  /* Get line from file */
	  if (fgets (new_line, sizeof(new_line), tmpFP) == NULL)
            break;
	  send(new_line, &connect_socket);
	}

	
	rc = Socket_putc(NEWLINE, connect_socket);
	check_put(rc, &connect_socket);

	if(no_error)
	  send(response, &connect_socket);
	
	rc = Socket_putc(STRING_END, connect_socket);
	check_put(rc, &connect_socket);

	/* delete the temporary file */
	remove(tmp_name);
	//      } 
      }
    }  
  }
}
示例#18
0
static NetDescriptor *
listenPortSingle(struct ListenState *listenState, struct addrinfo *info) {
	Socket *sock;
	int bindResult;
	int listenResult;
	NetDescriptor *nd;

	sock = Socket_openNative(info->ai_family, info->ai_socktype,
			info->ai_protocol);
	if (sock == Socket_noSocket) {
		int savedErrno = errno;
		log_add(log_Error, "socket() failed: %s.", strerror(errno));
		errno = savedErrno;
		return NULL;
	}

	(void) Socket_setReuseAddr(sock);
			// Ignore errors; it's not a big deal.
	if (Socket_setNonBlocking(sock) == -1) {
		int savedErrno = errno;
		// Error message is already printed.
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}
	
	bindResult = Socket_bind(sock, info->ai_addr, info->ai_addrlen);
	if (bindResult == -1) {
		int savedErrno = errno;
		if (errno == EADDRINUSE) {
#ifdef DEBUG
			log_add(log_Warning, "bind() failed: %s.", strerror(errno));
#endif
		} else
			log_add(log_Error, "bind() failed: %s.", strerror(errno));
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}

	listenResult = Socket_listen(sock, listenState->flags.backlog);
	if (listenResult == -1) {
		int savedErrno = errno;
		log_add(log_Error, "listen() failed: %s.", strerror(errno));
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}

	nd = NetDescriptor_new(sock, (void *) listenState);
	if (nd == NULL) {
		int savedErrno = errno;
		log_add(log_Error, "NetDescriptor_new() failed: %s.",
				strerror(errno));
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}
		
	NetDescriptor_setReadCallback(nd, acceptCallback);

	return nd;
}
示例#19
0
static void
acceptSingleConnection(ListenState *listenState, NetDescriptor *nd) {
	Socket *sock;
	Socket *acceptResult;
	struct sockaddr_storage addr;
	socklen_t addrLen;
	NetDescriptor *newNd;

	sock = NetDescriptor_getSocket(nd);
	addrLen = sizeof (addr);
	acceptResult = Socket_accept(sock, (struct sockaddr *) &addr, &addrLen);
	if (acceptResult == Socket_noSocket) {
		switch (errno) {
			case EWOULDBLOCK:
			case ECONNABORTED:
				// Nothing serious. Keep listening.
				return;
			case EMFILE:
			case ENFILE:
			case ENOBUFS:
			case ENOMEM:
#ifdef ENOSR
			case ENOSR:
#endif
				// Serious problems, but future connections may still
				// be possible.
				log_add(log_Warning, "accept() reported '%s'",
						strerror(errno));
				return;
			default:
				// Should not happen.
				log_add(log_Fatal, "Internal error: accept() reported "
						"'%s'", strerror(errno));
				explode();
		}
	}

	(void) Socket_setReuseAddr(acceptResult);
			// Ignore errors; it's not a big deal.
	if (Socket_setNonBlocking(acceptResult) == -1) {
		int savedErrno = errno;
		log_add(log_Error, "Could not make socket non-blocking: %s.",
				strerror(errno));
		Socket_close(acceptResult);
		errno = savedErrno;
		return;
	}
	(void) Socket_setInlineOOB(acceptResult);
			// Ignore errors; it's not a big deal as the other
			// party is not not supposed to send any OOB data.
	(void) Socket_setKeepAlive(sock);
			// Ignore errors; it's not a big deal.

#ifdef DEBUG
	{
		char hostname[NI_MAXHOST];
		int gniRes;

		gniRes = getnameinfo((struct sockaddr *) &addr, addrLen,
				hostname, sizeof hostname, NULL, 0, 0);
		if (gniRes != 0) {
			log_add(log_Error, "Error while performing hostname "
					"lookup for incoming connection: %s",
					(gniRes == EAI_SYSTEM) ? strerror(errno) :
					gai_strerror(gniRes));
		} else {
			log_add(log_Debug, "Accepted incoming connection from '%s'.",
					hostname);
		}
	}
#endif
	
	newNd = NetDescriptor_new(acceptResult, NULL);
	if (newNd == NULL) {
		int savedErrno = errno;
		log_add(log_Error, "NetDescriptor_new() failed: %s.",
				strerror(errno));
		Socket_close(acceptResult);
		errno = savedErrno;
		return;
	}

	doListenConnectCallback(listenState, nd, newNd,
			(struct sockaddr *) &addr, addrLen);
	// NB: newNd is now handed over to the callback function, and should
	//     no longer be referenced from here.
}
示例#20
0
int main(int argc, char* argv[])
{
  bool doneFlag = false;
  int i;
  int rc;
  int c;
  unsigned char tmp_name[MAX_TMP];
  unsigned char id_str[MAX_TMP];
  int id;
  int childPID, term_pid;
  int chld_status;
  char fc;
  char file_line[MAX_LINE];
  char * args[MAX_ARGS];


    /* variable names for file "handles" */
  FILE *tmpFP;
  FILE *fp;

  if (argc < 2)
  {
    printf("No port specified\n");
    return (-1);
  }

  /* create a "welcoming" socket at the specified port */
  welcome_socket = ServerSocket_new(atoi(argv[1]));
  if (welcome_socket < 0)
  {
    printf("Failed new server socket\n");
    return (-1);
  }

  id = (int) getpid();
  sprintf(id_str, "%d", id);
  strcpy(tmp_name,"tmp");
  strcat(tmp_name, id_str); 

  

     /* accept an incoming client connection; blocks the
      * process until a connection attempt by a client.
      * creates a new data transfer socket.
      */
      connect_socket = ServerSocket_accept(welcome_socket);
      if (connect_socket < 0)
      {
       printf("Failed accept on server socket\n");
       exit (-1);
     }

     Socket_close(welcome_socket);
     char input[MAX_LINE]={'\0'};
     memset(input,'\0',sizeof(char)*MAX_LINE);
     while(1){
      for (i = 0; i < MAX_LINE; i++) {
        c = Socket_getc(connect_socket);
        if (c == EOF) {
          remove(tmp_name);
          doneFlag = true;
          for (i=0; i<=strlen(ERROR2); i++){
            Socket_putc(ERROR2[i], connect_socket);
          }
         // printf("Socket_getc EOF or error\n"); 
          return; /* assume socket EOF ends service for this client */           
        }
        else {
          if (c == '\0') {
            input[i] = '\0';
            break;
          }
          if (c == '\n') {
            i--;
          }
          else{       
           input[i] = c;
         }
       }
     }

       /* be sure the string is terminated if max size reached */
     if (i == MAX_LINE) input[i-1] = '\0';


     fp = freopen(tmp_name, "w", stdout);
     childPID = fork();

     if (childPID == 0){
        //code for child: 

      char * token = strtok(input, " \t");

        args[0] = token; // set first "argument" to the command itself

        int count = 1;
        // loop to fill args[] with the remaining arguments (if any)
        while (token != NULL) {
          token = strtok(NULL, " ");
          
          args[count] = token;
          count++;
          if (count > (MAX_ARGS+2)){
            // handle it
          }
        }
        
        args[count] = NULL; // the array must be null terminated for execvp() to work
        int execCode = execvp(args[0], args);
        if (execCode == -1) {
          for (i=0; i<=strlen(ERROR1); i++){
            Socket_putc(ERROR1[i], connect_socket);
          }
         // exit(0);
          //goto end;
         // printf("Error: invalid command.\n");
        }
      }

      else if (childPID == -1) {
        printf("Problem forking.\n");
      }
      
      else {
        //parent code:
        term_pid = waitpid(childPID, &chld_status, 0);
        if (doneFlag == false){
         char file_c;

         if ((tmpFP = fopen (tmp_name, "r")) == NULL) {
          fprintf (stderr, "error opening tmp file\n");
          exit (-1);
        }
        while ((fc = fgetc(tmpFP)) != EOF) {
          Socket_putc(fc, connect_socket);
        }
      }

      if (term_pid == -1) 
        perror("waitpid"); 

      else
      {
        if (WIFEXITED(chld_status)) {
          char str[] = "PID %d exited, status = %d\n";
          char str2[256];
          sprintf(str2, str, childPID, WEXITSTATUS(chld_status));
          for (i=0; i<=strlen(str2); i++){
            Socket_putc(str2[i], connect_socket);
          }
           //printf("PID %d exited, status = %d\n", childPID, WEXITSTATUS(chld_status));
        }
        else{
         printf("PID %d did not exit normally\n", childPID);
        }
     }
     


   }

   end:;
 }

 Socket_close(connect_socket);
 exit (0);
}
示例#21
0
/**
 * Process an incoming connect packet for a socket
 * @param pack pointer to the connect packet
 * @param sock the socket on which the packet was received
 * @return completion code
 */
int MQTTProtocol_handleConnects(void* pack, int sock, Clients* client)
{
	Connect* connect = (Connect*)pack;
	Node* elem = NULL;
	int terminate = 0;
	int rc = TCPSOCKET_COMPLETE;
#if !defined(SINGLE_LISTENER)
	Listener* listener = Socket_getParentListener(sock);
#endif

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 26, NULL, sock, connect->clientID);/*
			connect->Protocol, connect->flags.bits.cleanstart, connect->keepAliveTimer,
			connect->version, connect->username, connect->password);*/
	Socket_removeNew(sock);		
			
	if (bstate->state != BROKER_RUNNING)
		terminate = 1; /* don't accept new connection requests when we are shutting down */
	/* Now check the version.  If we don't recognize it we will not have parsed the packet,
	 * so nothing else in the packet structure will have been filled in.
	 */
	else if (!MQTTPacket_checkVersion(pack))
	{
		Log(LOG_WARNING, 32, NULL, connect->Protocol, connect->version);
		rc = MQTTPacket_send_connack(CONNACK_UNACCEPTABLE_PROTOCOL_VERSION, sock, Socket_getpeer(sock)); /* send response */
		terminate = 1;
	}
	else if (connect->clientID[0] == '\0' || (connect->version == 3 && strlen(connect->clientID) > 23))
	{
		rc = MQTTPacket_send_connack(CONNACK_IDENTIFIER_REJECTED, sock, Socket_getpeer(sock)); /* send response */
		terminate = 1;
	}
	else if (bstate->password_file != NULL)
	{
		if (connect->flags.bits.username && connect->flags.bits.password &&
				(Users_authenticate(connect->username, connect->password) == false))
		{
			Log(LOG_WARNING, 31, NULL, connect->clientID);
			rc = MQTTPacket_send_connack(CONNACK_BAD_USERNAME_OR_PASSWORD, sock, connect->clientID); /* send bad user/pass response */
			terminate = 1;
		}
		else if ((!connect->flags.bits.username || !connect->flags.bits.password) && !bstate->allow_anonymous)
		{
			Log(LOG_WARNING, 31, NULL, connect->clientID);
			rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send broker unavailable response */
			terminate = 1;
		}
	}

	if (terminate)
		;
	else if (bstate->clientid_prefixes->count > 0 &&
		!ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare))
	{
		Log(LOG_WARNING, 31, NULL, connect->clientID);
		terminate = 1;
	}
	else
	{
#if !defined(SINGLE_LISTENER)
		if (listener->max_connections > -1 &&
				listener->connections->count > listener->max_connections)
		{
			Log(LOG_WARNING, 141, NULL, connect->clientID, listener->max_connections, listener->port);
#else
		if (bstate->max_connections > -1 &&
			MQTTProtocol_getNoConnectedClients() >= bstate->max_connections)
		{
			Log(LOG_WARNING, 141, NULL, connect->clientID, bstate->max_connections, bstate->port);
#endif
			rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send response */
			terminate = 1;
		}
	}

	if (terminate)
	{
		MQTTPacket_freeConnect(connect);
		Socket_close(sock);
		rc = TCPSOCKET_COMPLETE;
		goto exit;
	}

	if (bstate->connection_messages)
		Log(LOG_INFO,
#if !defined(SINGLE_LISTENER)
			33, NULL, listener->port, connect->clientID, Socket_getpeer(sock));
#else
			33, NULL, bstate->port, connect->clientID, Socket_getpeer(sock));
#endif

	elem = TreeFindIndex(bstate->clients, connect->clientID, 1);
	if (elem == NULL)
	{
		client = TreeRemoveKey(bstate->disconnected_clients, connect->clientID);
		if (client == NULL)
		{
			int i;
			char* tmpAddr = NULL;

			client = malloc(sizeof(Clients));
			memset(client, '\0', sizeof(Clients));
			tmpAddr = Socket_getpeer(sock);
			client->addr = malloc(strlen(tmpAddr)+1);
			strcpy(client->addr, tmpAddr);
	#if defined(MQTTS)
			client->protocol = PROTOCOL_MQTT;
	#endif
			client->clientID = connect->clientID;
			client->outboundMsgs = ListInitialize();
			client->inboundMsgs = ListInitialize();
			for (i = 0; i < PRIORITY_MAX; ++i)
				client->queuedMsgs[i] = ListInitialize();
			connect->clientID = NULL; /* don't want to free this space as it is being used in the client structure */
		}
		client->socket = sock;
		TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
	}
	else
	{
		client = (Clients*)(elem->content);
		if (client->connected)
		{
			Log(LOG_INFO, 34, NULL, connect->clientID, Socket_getpeer(sock));
			if (client->socket != sock)
				Socket_close(client->socket);
		}

		if (connect->flags.bits.cleanstart)
		{
			int i;
			/* empty pending message lists */
			MQTTProtocol_emptyMessageList(client->outboundMsgs);
			MQTTProtocol_emptyMessageList(client->inboundMsgs);
			for (i = 0; i < PRIORITY_MAX; ++i)
				MQTTProtocol_emptyMessageList(client->queuedMsgs[i]);
			client->msgID = client->outbound = client->ping_outstanding = 0;
		}

		/* have to remove and re-add client so it is in the right order for new socket */
		if (client->socket != sock)
		{
			TreeRemoveNodeIndex(bstate->clients, elem, 1);
			TreeRemoveKeyIndex(bstate->clients, &client->socket, 0);
			client->socket = sock;
			TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
		}
	}

	client->good = client->connected = 1;
	client->cleansession = connect->flags.bits.cleanstart;
	client->keepAliveInterval = connect->keepAliveTimer;
	client->noLocal = (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0;
	if (client->cleansession)
		MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */
#if !defined(SINGLE_LISTENER)
	if (listener && listener->mount_point && connect->flags.bits.will)
	{
		char* temp = malloc(strlen(connect->willTopic) + strlen(listener->mount_point) + 1);
		strcpy(temp, listener->mount_point);
		strcat(temp, connect->willTopic);
		free(connect->willTopic);
		connect->willTopic = temp;
	}
#endif
#if defined(MQTTS)
	if (connect->flags.bits.will)
	{
		MQTTProtocol_setWillTopic(client, connect->willTopic,
									connect->flags.bits.willRetain, connect->flags.bits.willQoS);
		MQTTProtocol_setWillMsg(client, connect->willMsg);
		connect->willTopic = NULL;
		connect->willMsg = NULL;
	}
#else
	MQTTProtocol_setWill(connect, client);
#endif

	if (connect->flags.bits.username)
	{
		client->user = Users_get_user(connect->username);
	}

	rc = MQTTPacket_send_connack(CONNACK_CONNECTION_ACCEPTED, sock, client->clientID); /* send response */

	if (client->cleansession == 0)
	{
		ListElement* outcurrent = NULL;
		time_t now = 0;

		/* ensure that inflight messages are retried now by setting the last touched time
		 * to very old (0) before calling the retry function
		 */
		time(&(now));
		while (ListNextElement(client->outboundMsgs, &outcurrent))
		{
			Messages* m = (Messages*)(outcurrent->content);
			m->lastTouch = 0;
		}
		MQTTProtocol_retries(now, client);
		MQTTProtocol_processQueued(client);
	}
	time(&(client->lastContact));

	MQTTPacket_freeConnect(connect);

exit:
	FUNC_EXIT_RC(rc);
	return rc;
}


/**
 * Process an incoming ping request packet for a socket
 * @param pack pointer to the publish packet
 * @param sock the socket on which the packet was received
 * @return completion code
 */
int MQTTProtocol_handlePingreqs(void* pack, int sock, Clients* client)
{
	int rc = TCPSOCKET_COMPLETE;

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 3, NULL, sock, client->clientID);
	rc = MQTTPacket_send_pingresp(sock, client->clientID);
	FUNC_EXIT_RC(rc);
	return rc;
}
示例#22
0
int main(int argc, char *argv[])
{
  int ID;
  char line[MAX_LINE];
  FILE *tmp;
  FILE *output;

  //Argument 1: Welcoming port
  if (argc < 2)
  {
    printf("No port specified\n");
    exit(-1);
  }

  /* Create a welcome socket at the specified port */
  welcome_socket = ServerSocket_new(atoi(argv[1]));
  if (welcome_socket < 0)
  {
    printf("Failed new server socket\n");
    exit(-1);
  }

  /* Open a connect socket through the welcom socket*/
  connect_socket = ServerSocket_accept(welcome_socket);
  if (connect_socket < 0)
  {
    printf("Failed connect socket\n");
    exit(-1);
  }

  Socket_close(welcome_socket);  //Close the welcome socket as it is unused

  pid_t childPID;
  char *argcv[MAXARGSIZE];
  int child_status;

  /* Run until exited*/
  while ( 1 )
  {
    ID = (int)getpid();                    // Get PID of the Current Process
    sprintf(filename, "tmp%d", ID);        // Make file name from the current pid
    tmp = freopen(filename, "w", stdout);  // Redirect stdout to the tmp file

    read_line(line);
  
    childPID = fork();  //Child Process to read from client and execute
    if (childPID < 0)
    {
      printf("Fork error\n");
      exit(-1);
    }

    if (childPID == 0)  //Child process
    {
      tokenize(line, argv);  //Tokenize the input line into arguments
      errno = 0;
      // Check if the file name is valid
      if (execvp(*argv, argv) == -1 ) //Run the command in the arguments list
      {
	printf("Execvp error: %d\n", errno);
        exit(-1);
      }      
    }
    else if (childPID > 0)
    {
      int flag = 0;

      //Wait until the child process finishes
      if (waitpid(-1, &child_status, 0) == -1) {
	printf("Server: wait error\n");
      }
      //Check signals for child process
      if (WIFSIGNALED(child_status)) {
	printf("Server: WIFSIGNALED ERROR: %d\n", WTERMSIG(child_status));
      }
      else if (WIFSTOPPED(child_status)) {
	printf("Server: WIFSTOPPED ERROR: %d\n", WSTOPSIG(child_status));
      }
 
      fclose(tmp);  //Close the redirected temp file

      output_results();  //Ouput thte reuslts back into socket
    }
  }
}
示例#23
0
// actually does the execution and reports back to ForkExecuteRedirect
void ForkExecuteRedirect_helper(int argc, char *argv[]){
  pid_t cpid, term_pid; /* type for Linux process id */
  int chld_status; 
  int i;
  int execCheck;
  char *parms_array[NUM_PARMS];  /* arrary of pointers to strings */
  unsigned char new_line[MAX_LINE];
  unsigned char tmp_name[MAX_TMP];
  unsigned char id_str[MAX_TMP];
  int id;

  /* variable names for file "handles" */
  FILE *tmpFP;
  FILE *fp;

  /* The positional parameters passed to this program as pointers to 
   * strings can just be passed on to execvp which requires a
   * NULL-terminated array of pointers to strings.  By convention, the
   * first entry in the array is the file name to be executed, and the
   * next non-null pointers are for positional parameters to that program.
   */

  /* get the parent process ID and use it to create a file name for the
   * temporary file with the format "tmpxxxxx" where xxxxx is the ID 
   */

  id = (int) getpid();
  sprintf(id_str, "%d", id);
  strcpy(tmp_name,"tmp");
  strcat(tmp_name, id_str);    

  /* create child process, report error if present and exit */  
  cpid = fork(); 
  if (cpid == -1) 
  {
    perror("fork"); /* perror creates description of OS error codes */
    exit(ERR_RETURN); 
  }

  /* conditional execution of statements depending on whether the code is
   * if running as the parent or child process.
   */

  if (cpid == 0) 
  { /* the child process */
    /* dynamically redirect stdout to the named temporary 
     * file open for writing
     */ 
    fp = freopen(tmp_name, "w", stdout); 

    /* do the OS execvp() call, if there is an error return, report it.  Otherwise
     * this call will not return and the new image will execute as this process ID.
     */

    execCheck = execvp(argv[0], argv);
 
    if (execCheck == -1) 
    {
      perror("execvp, execCheck == -1"); 
      exit(-1); 
    }
  }  /* end of code that can be executed by the child process */
  else 
  {/* code executed by the parent process */
    /* wait for the child to terminate and determine its exit status */
    /* this is necessary to prevent the accumulation of "Zombie" processes */

    term_pid = waitpid(cpid, &chld_status, 0);
    if (term_pid == -1) 
      perror("waitpid"); 
    else
    {
      if (WIFEXITED(chld_status)) 
        printf("PID %d exited, status = %d\n", cpid, WEXITSTATUS(chld_status));
      else
        printf("PID %d did not exit normally\n", cpid);
    }

    if ((tmpFP = fopen (tmp_name, "r")) == NULL) {
      fprintf (stderr, "error opening tmp file\n");
      exit (-1);
    }
    while (!feof (tmpFP)) {
      /* Get line from file */

      if (fgets (new_line, sizeof(new_line), tmpFP) == NULL)
        break;
      int toClientCount = strlen(new_line);
      int new_index;
      char toClientChar;
      int new_rc;
      for (new_index = 0; new_index < toClientCount; new_index++){
        toClientChar = new_line[new_index];
        new_rc = Socket_putc(toClientChar, connect_socket);
        if (new_rc == EOF){
          printf("Socket_putc EOF or error\n");             
          Socket_close(connect_socket);
          exit (-1);  // assume socket problem is fatal, end client
        }
      }
    }
    // delete the temporary file 
    remove(tmp_name);
  } // end of code that can be executed by the parent process
  exit(0);
}
示例#24
0
// Try connecting to the next address.
static Socket *
tryConnectHostNext(ConnectState *connectState) {
	struct addrinfo *info;
	Socket *sock;
	int connectResult;

	assert(connectState->nd == NULL);

	info = connectState->infoPtr;

	sock = Socket_openNative(info->ai_family, info->ai_socktype,
			info->ai_protocol);
	if (sock == Socket_noSocket) {
		int savedErrno = errno;
		log_add(log_Error, "socket() failed: %s.\n", strerror(errno));
		errno = savedErrno;
		return Socket_noSocket;
	}
	
	if (Socket_setNonBlocking(sock) == -1) {
		int savedErrno = errno;
		log_add(log_Error, "Could not make socket non-blocking: %s.\n",
				strerror(errno));
		errno = savedErrno;
		return Socket_noSocket;
	}

	(void) Socket_setReuseAddr(sock);
			// Ignore errors; it's not a big deal.
	(void) Socket_setInlineOOB(sock);
			// Ignore errors; it's not a big deal as the other party is not
			// not supposed to send any OOB data.
	(void) Socket_setKeepAlive(sock);
			// Ignore errors; it's not a big deal.

	connectResult = Socket_connect(sock, info->ai_addr, info->ai_addrlen);
	if (connectResult == 0) {
		// Connection has already succeeded.
		// We just wait for the writability callback anyhow, so that
		// we can use one code path.
		return sock;
	}

	switch (errno) {
		case EINPROGRESS:
			// Connection in progress; wait for the write callback.
			return sock;
	}

	// Connection failed immediately. This is just for one of the addresses,
	// so this does not have to be final.
	// Note that as the socket is non-blocking, most failed connection
	// errors will usually not be reported immediately.
	{
		int savedErrno = errno;
		Socket_close(sock);
#ifdef DEBUG
		log_add(log_Debug, "connect() immediately failed for one address: "
				"%s.\n", strerror(errno));
				// TODO: add the address in the status message.
#endif
		errno = savedErrno;
	}
	return Socket_noSocket;
}
示例#25
0
static int closeSock(struct Allocator_OnFreeJob* j)
{
    Socket_close((int)(uintptr_t)j->userData);
    return 0;
}
示例#26
0
int MQTTSProtocol_handleConnacks(void* pack, int sock, char* clientAddr)
{
	MQTTS_Connack* connack = (MQTTS_Connack*)pack;
	int rc = 0;
	Clients* client = NULL;
	BridgeConnections* bc = Bridge_getBridgeConnection(sock);

	FUNC_ENTRY;
	if (bc == NULL)
	{
		rc = SOCKET_ERROR;
		goto exit;
	}

	if (bc->primary && bc->primary->socket == sock)
		client = bc->primary;
	else
		client = bc->backup;

	if (connack->returnCode != MQTTS_RC_ACCEPTED)
	{
		if (client)
		{
			if (client->noLocal == 1)
				client->noLocal = 0;
			else
				Log(LOG_WARNING, 132, NULL, connack->returnCode, client->clientID);
			MQTTProtocol_closeSession(client, 0);
		}
		else
			Socket_close(sock);
	}
	else if (client)
	{
		ListElement* addr = bc->cur_address;

		if (client == bc->primary && bc->round_robin == 0)
			addr = bc->addresses->first;
		Log(LOG_INFO, 133, NULL, bc->name, (char*)(addr->content));

		client->connect_state = 3;  //should have been 2 before
		bc->last_connect_result = connack->returnCode;
		(bc->no_successful_connections)++;
		client->connected = 1;
		client->good = 1;
		client->ping_outstanding = 0;
		time(&(client->lastContact));


		if (client->will)
		{
			Publish pub;
			Messages* m = NULL;
			MQTTProtocol_sys_publish(client->will->topic, "1");
			pub.payload = "1";
			pub.payloadlen = 1;
			pub.topic = client->will->topic;
			MQTTProtocol_startOrQueuePublish(client, &pub, 0, client->will->retained, &m);
		}


		if (client == bc->primary &&
			(bc->backup && (bc->backup->connected == 1 || bc->backup->connect_state != 0)))
		{
			Log(LOG_INFO, 134, NULL, (char*)(bc->cur_address->content));
			MQTTProtocol_closeSession(bc->backup, 0);
		}

		//if (bc->addresses->count > 1 || bc->no_successful_connections == 1)
		Bridge_subscribe(bc, client);
	}

	//Clients* client = Protocol_getclientbyaddr(clientAddr);

	MQTTSPacket_free_packet(pack);

exit:
	FUNC_EXIT_RC(rc);
	return rc;
}