コード例 #1
0
void ARXFlatBufferMgrImpl::freeBuffers()
{
    registerClient(NULL);
    for (unsigned int i = 0; i < IBufferMgr::MAX_BUFFERS; i++) {
        mBuffers[i].clear();
    }
}
コード例 #2
0
ファイル: i2c.cpp プロジェクト: pgbaum/bbExamples
// TODO: allow more than one device
I2C::I2C( const char *device, int address )
{
   if( (dev = open( device, O_RDWR ) ) < 0)
      throw std::invalid_argument(
            std::string( "I2C: Unable to open device: " )
            + strerror( errno ) );
   registerClient( address );
}
コード例 #3
0
ファイル: EntriesManager.cpp プロジェクト: Samsung/cynara
bool EntriesManager::modifyClient(RequestContext::ClientId clientId, uint16_t bufferSize) {
    auto clientIt = m_clients.find(clientId);
    if (clientIt == m_clients.end()) {
        LOGE("Unknow client [" << clientId << "]");
        return false;
    }
    clientIt->second.bufferSize = bufferSize;
    registerClient(clientId, clientIt);
    return true;
}
コード例 #4
0
void DisplayRefreshMonitorManager::windowScreenDidChange(PlatformDisplayID displayID, DisplayRefreshMonitorClient& client)
{
    if (client.hasDisplayID() && client.displayID() == displayID)
        return;
    
    unregisterClient(client);
    client.setDisplayID(displayID);
    registerClient(client);
    if (client.isScheduled())
        scheduleAnimation(client);
}
コード例 #5
0
//------------------------------------------------------------------------------
void ServerFiber::main()
{
  server_->config_->parse();
  stdErr.setDebugLevels(server_->config_->value("debug_levels","+0,+1,+2,+3"));
  union {
    uint8_t cmd;
    uint8_t ui8;
  };
  auth();
  while( !terminated_ ){
    *this >> cmd;
    switch( cmd ){
      case cmQuit :
        putCode(eOK);
        terminate();
        break;
      case cmGetProcessStartTime :
        *this << getProcessStartTime();
        break;
      case cmSelectServerType :
        *this >> ui8;
        putCode(ui8 < stCount ? eOK : eInvalidServerType);
        serverType_ = ServerType(ui8);
        break;
      case cmRegisterClient :
        registerClient();
        break;
      case cmRegisterDB :
        registerDB();
        break;
      case cmGetDB :
        getDB();
        break;
      case cmSendMail :
        sendMail();
        break;
      case cmRecvMail :
        recvMail();
        break;
      case cmRemoveMail :
        removeMail();
        break;
      case cmSelectProtocol :
        *this >> ui8;
        putCode(ui8 < 2 ? eOK : eInvalidProtocol);
        protocol_ = ui8;
        break;
      default : // unrecognized or unsupported command, terminate
        putCode(eInvalidCommand);
        terminate();
    }
  }
}
コード例 #6
0
ファイル: CAN_VSCOM.cpp プロジェクト: Huigang610/busmaster-1
/**
* @brief         Performs intial operations.
*                Initializes filter, queue, controller config with default values.
* @param         void
* @return        S_OK if the open driver call successfull otherwise S_FALSE
*/
HRESULT CDIL_CAN_VSCOM::performInitOperations(void)
{
    DWORD dwClientID;

    memset(&sg_VSCanCfg, 0, sizeof(sg_VSCanCfg));

    /* Create critical section for ensuring thread
    safeness of read message function */
    InitializeCriticalSection(&sg_DIL_CriticalSection);
    /* Register Monitor client */
    dwClientID = 0;
    registerClient(TRUE, dwClientID, CAN_MONITOR_NODE);

    return(S_OK);
}
コード例 #7
0
ファイル: wgt.cpp プロジェクト: z80/robocam
Wgt::Wgt( QWidget * parent )
: QWidget( parent )
{
    ui.setupUi( this );
    connect( ui.connect,        SIGNAL(clicked()), this, SLOT(connectHost()) );
    connect( ui.registerClient, SIGNAL(clicked()), this, SLOT(registerClient()) );
    connect( ui.send,           SIGNAL(clicked()), this, SLOT(send()) );
    connect( ui.sendFile,       SIGNAL(clicked()), this, SLOT(sendFile()) );
    connect( ui.status,         SIGNAL(clicked()), this, SLOT(status()) );
    connect( ui.clear,          SIGNAL(clicked()), this, SLOT(clear()) );

    connect( this, SIGNAL(sigLog(const QString &)), this, SLOT(slotLog(const QString &)), Qt::QueuedConnection );

    xmpp.setMessageHandler( boost::bind( &Wgt::messageHandler, this, _1, _2 ) );
    xmpp.setLogHandler( boost::bind( &Wgt::logHandler, this, _1 ) );
}
コード例 #8
0
ファイル: EntriesManager.cpp プロジェクト: Samsung/cynara
bool EntriesManager::addClient(RequestContext::ClientId clientId, uint16_t bufferSize) {
    if (clientId == RequestContext::InvalidClientId) {
        LOGE("Invalid client id");
        return false;
    }
    if (m_clients.find(clientId) != m_clients.end()) {
        LOGE("Client [" << clientId << "] already exists, use modify instead");
        return false;
    }
    /*
     * For the first time client is registered for future entry, after this its state is kept,
     * so client can fetch entries continuously
     */
    EntriesQueue::EntryId startPoint = m_container.getBackEntryId();
    auto itInfo = m_clients.emplace(clientId, ClientInfo(clientId, startPoint, bufferSize));
    addEntryCount(startPoint, itInfo.first);
    registerClient(clientId, itInfo.first);
    return true;
}
コード例 #9
0
bool TextClientManager::processDeregisterCommand(const std::string &command,
    const Poco::Net::SocketAddress &address) {
    char buf[16] = { 0 };
    if (sscanf(command.c_str(), "register %s", buf) != 1) {
        return false;
    }
    buf[sizeof(buf)-1] = 0;
    Poco::Net::DatagramSocket *socket = NULL;
    if (strcmp("all", buf) == 0) {
        socket = registerDefault(address);
    }
    else {
        socket = registerClient(atoi(buf), address);
    }
    if (socket) {
        const char *response = "registered";
        socket->sendBytes(response, strlen(response));
    }
    return true;
}
コード例 #10
0
ファイル: client.c プロジェクト: sclaxton/chirc
void wait4Register(cli *client, blist messages, bstring incompleteMessage){
    incompleteMessage = incompleteMessage ? incompleteMessage : safe_BfromCstr("");

    /*recv messages until you receive a nick and user msg*/
    bstring raw;
    int i = handleRegisterMessages(messages, client);
    while (!(client->nick && client->user)){
        raw = safeRecv(client);
        messages = extractMessages(raw, &incompleteMessage);
        i = handleRegisterMessages(messages, client);
    }

    /*trim message list to be the list of messages recv'd*/
    /*after the client completed registration*/
    blistDeleteRange(messages, 0, i);

    /*complete client registration*/
    registerClient(client, messages, incompleteMessage);

}
コード例 #11
0
ファイル: server.hpp プロジェクト: hubertwe/BusLab
    void serveClient(ClientDesc client)
    {   
        SSL* ssl;
        ssl = client.ssl;

        Message req;
        req = receive(ssl);

        switch (req.getType())
        {
            case Message::REGISTER_REQ :
            {
                registerClient(req, client);
                break;
            }

            case Message::TEXT_MSG : 
            {
                forwardMessage(req, client);
                break;
            }

            case Message::BROADCAST_MSG : 
            {
                broadcastTextMessageToAll(req, client);
                break;
            }

            case Message::CLIENT_QUIT_IND : 
            {
                forgetAboutClient(client);
                broadcastInfoAboutQuitClient(client);
                break;
            }

            default:
            {
                break;
            }
        }
    }
コード例 #12
0
ファイル: ofApp.cpp プロジェクト: jedahan/osc_skeleton_hub
//--------------------------------------------------------------
void ofApp::update(){
    
    int time = ofGetElapsedTimeMillis();
    
    if (time - lastPulseTime > PULSE_INTERVAL) {
        lastPulseTime = time;
        sendPulse();
    }
    
    while(oscReceiver.hasWaitingMessages()){
		// get the next message
		ofxOscMessage m;
		oscReceiver.getNextMessage(&m);
        
        // handle heartbeat
        if(m.getAddress() == "/call/home"){
			registerClient(&m);
		}
    }

}
コード例 #13
0
ファイル: client_PFS.c プロジェクト: ashishbedi/netsys
////////////////////////////////////////////////////////////////////////////////
// Funciton to connect and register and all that nonsense
void connectPlease( Folder *dir, int sock ) {
  int nbytes;                // Number of bytes
  char buffer[ MAXBUFSIZE ]; // Buffer

  nbytes = write( sock, "CONNECT", MAXBUFSIZE );
  ERROR( nbytes < 0 );
  
  bzero( buffer, MAXBUFSIZE );
  nbytes = read( sock, buffer, MAXBUFSIZE );
  ERROR ( nbytes < 0 );
  switch ( parseCmd( buffer ) ) {
  case CONNECT:
	{
	  printf( "$ Connection Established\n" );
	  switch ( registerClient( dir, sock ) ) {
	  case FAILURE: 
		{
		  printf( "$ There is already a user with the name '%s' on the server.\n", 
				  dir->name );
		  close( sock );
		  exit( EXIT_SUCCESS );
		}
	  case SUCCESS:
		{
		  printf( "$ You have been connected as %s\n", dir->name );
		  sendList( dir, sock );
		  break;
		}
	  }	  
	  break;
	}
  default: 
	{
	  printf( "$ Error in registering\n" );
	}
  }
} // connectionPlease( )
コード例 #14
0
ファイル: client.cpp プロジェクト: keequenliu/glut_opengl
bool Client::init(int*argc,char ** argv,BaseModel *model)
{
    glutInit(argc,argv);
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ALPHA );
    glutInitWindowPosition( 100, 100 );
    glutInitWindowSize(1024, 768 );
    glutCreateWindow("glut-opengl");

    if(glewInit()!=GLEW_OK)
    {
        fprintf(stderr,"Fail to initialize GLEW \n");
        return false;
    }
    s_client=this;
    /** init GL **/
    glClearColor(0.2f,0.2f,0.4f,0.0f);
    glEnable(GL_TEXTURE_2D);

    /** register glut method **/
    registerClient();

    /** test method **/
    m_model=model;
    m_model->load();

#ifdef KEE_SHADER
    m_programID=Shader::loadShaders("vertex.txt", "fragment.txt");
    m_matrixID=glGetUniformLocation(m_programID,"MVP");
    projectViewModel();
#endif

    angle_x=0.0f;
    angle_y=0.0f;

    return true;
}
コード例 #15
0
ファイル: Server.cpp プロジェクト: djurodrljaca/lib-data-bus
void DataBus::Server::processPackets(Client *client)
{
    // Check client
    if (client == 0)
    {
        // Error, null pointer
        return;
    }

    // Find client in the list
    int index = m_clients.indexOf(client);

    if (index < 0)
    {
        // Error, client was not found
        return;
    }

    // Process all packets
    while (client->packetsAvailable())
    {
        // Process packet
        Packet packet = client->takePacket();

        switch (packet.getPacketType())
        {
            case PacketType_RegisterClientRequest:
            {
                // Try to register the client
                quint8 returnStatus = registerClient(client, packet);

                // Send Register Client Response
                Packet responsePacket;

                if (RegisterClientResponsePacket::create(packet.getSource(),
                                                         packet.getPacketId(),
                                                         returnStatus,
                                                         &responsePacket) == false)
                {
                    // Error, failed to create packet
                    break;
                }

                client->sendPacket(responsePacket);
                break;
            }

            case PacketType_GetClientListRequest:
            {
                // Create response
                Packet responsePacket;
                QList<quint8> clientIdList = getRegisteredClientIdList();

                if (GetClientListResponsePacket::create(packet.getSource(),
                                                        packet.getPacketId(),
                                                        clientIdList,
                                                        &responsePacket) == false)
                {
                    // Error, failed to create packet
                    break;
                }


                // Send Get Client List Response
                client->sendPacket(responsePacket);
                break;
            }

            case PacketType_GetClientStatusRequest:
            {
                // Parse packet
                quint8 clientId;

                if (DataBus::GetClientStatusRequestPacket::parse(packet,
                                                                 &clientId) == false)
                {
                    // Error, failed to parse packet
                    break;
                }

                // Create response
                ClientStatus clientStatus = getRegisteredClientStatus(clientId);

                Packet responsePacket;

                if (GetClientStatusResponsePacket::create(packet.getSource(),
                                                          packet.getPacketId(),
                                                          clientId,
                                                          clientStatus,
                                                          &responsePacket) == false)
                {
                    // Error, failed to create packet
                    break;
                }


                // Send Get Client Status Response
                client->sendPacket(responsePacket);
                break;
            }

            default:
            {
                // Forward packet to a client
                forwardPacket(packet);
                break;
            }
        }
    }
}
コード例 #16
0
/*
 * Main routine of our mini time server
 */
int
main(int argc, char* argv[])
{
	establishRedirection("mtimesrv.log", REDIR_OUT_APPEND, STDOUT_FILENO | STDERR_FILENO);

	printf("\nMicro Time Server\nVersion: %s\n\n", MTIMESRV_VERSION);

	init();
	daemonize();

	/* main server loop */
	while(1)
	{
		ipc_packet_data.sem_id  = status.sem_id;
		ipc_packet_data.reqresp = &request;
		
		if(receiveRequest(&ipc_packet_data) < 0)
		{
			ipcerror("mtimesrv::main():receiveRequest() - failed");
			exit(1);
		}
		
		/* Dispatch requests */
		switch(request.command)
		{
			case IDLE:
				printf("Idle\n");
				fflush(stdout);
				break;

			case TIME:
				sendTime();
				break;

			case OPEN:
				registerClient();
				break;

			case VERSION:
				sendVersion();
				break;

			case TERMINATE:
				terminate();
				break;

			case PING:
				processPing();
				break;

			default:
				printf("Unsupported command (%d) from a client (PID=%d)... Ignored.\n", request.command, request.client_pid);
				fflush(stdout);
				break;
		}

		/* Reset the request buffer */
		memset(&request, 0, sizeof(request_t));
	}

	return 0;
}
コード例 #17
0
ファイル: AppleGPIO.cpp プロジェクト: AzerTyQsdF/osx
IOReturn AppleGPIO::callPlatformFunction(const OSSymbol *functionName,
                                         bool waitForFunction,
                                         void *param1, void *param2,
                                         void *param3, void *param4 )
{
	DLOG("AppleGPIO::callPlatformFunction %s %s %08lx %08lx %08lx %08lx\n",
			functionName->getCStringNoCopy(), waitForFunction ? "TRUE" : "FALSE",
			(UInt32)param1, (UInt32)param2, (UInt32)param3, (UInt32)param4);

	if (fPlatformFuncArray)
	{
		UInt32 i;
		IOPlatformFunction *pfFunc;
		
		UInt32 count = fPlatformFuncArray->getCount();
		for (i = 0; i < count; i++)
		{
			if (pfFunc = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i)))
			{
				DLOG ("AppleGPIO::callPlatformFunction '%s' - got platformFunction object\n",
						functionName->getCStringNoCopy());

				// If param4 is an OSSymbol reference, check for interrupt event registration
				// or enable/disable symbols
				if (pfFunc->platformFunctionMatch(functionName, kIOPFFlagIntGen, NULL))
				{
					OSSymbol *subFunctionSym;
					
					DLOG ("AppleGPIO::callPlatformFunction '%s' - got platformFunction interrupt match\n",
							functionName->getCStringNoCopy());

					if (param4 && (subFunctionSym = OSDynamicCast(OSSymbol, (const OSMetaClassBase *)param4)))
					{
						DLOG ("AppleGPIO::callPlatformFunction '%s', subFunction '%s'\n",
								functionName->getCStringNoCopy(), subFunctionSym->getCStringNoCopy());

						if (subFunctionSym == fSymIntRegister)
							return (registerClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntUnRegister)
							return (unregisterClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntEnable)
							return (enableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntDisable)
							return (disableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						return kIOReturnBadArgument;			// Unknown function
					}
					else
					{
						DLOG ("AppleGPIO::callPlatformFunction '%s', param4 not a OSSymbol\n",
								functionName->getCStringNoCopy());
					}
				}

				// Check for on-demand case
				if (pfFunc->platformFunctionMatch (functionName, kIOPFFlagOnDemand, NULL))
				{
					DLOG ("AppleGPIO::callPlatformFunction '%s', calling demand function\n",
							functionName->getCStringNoCopy());

					return (performFunction (pfFunc, param1, param2, param3, param4) ? kIOReturnSuccess : kIOReturnBadArgument);
				}

				DLOG ("AppleGPIO::callPlatformFunction '%s' - got no match\n", functionName->getCStringNoCopy());
			}
		}

#ifdef OLD_STYLE_COMPAT

		// Need to catch old-style register-, unregister-, enable-, disable- commands

		DLOG ("AppleGPIO::callPlatformFunction '%s' - handling old style\n", functionName->getCStringNoCopy());

		// Is it an interrupt notification registration request?
		if (fRegisterStrings &&
		    fRegisterStrings->containsObject(functionName))
		{
			return (registerClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		// unregister?
		else if (fUnregisterStrings && 
		         fUnregisterStrings->containsObject(functionName))
		{
			return (unregisterClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		else if (fEnableStrings &&
		         fEnableStrings->containsObject(functionName))
		{
			return (enableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		else if (fDisableStrings &&
		         fDisableStrings->containsObject(functionName))
		{
			return (disableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}

#endif

	}

	DLOG("AppleGPIO::callPlatformFunction unrecognized function\n");

	return super::callPlatformFunction(functionName, waitForFunction, param1, param2,
			param3, param4);

}
コード例 #18
0
void *accept_thread(void *accept_sock)
{
    //socket descriptor for each client
    int acptsock;
    //Retrieve the socket that passed from pthread_create
    acptsock= (intptr_t)accept_sock;

    //Buffer to send&receive data//
    char buf[256];

    //Received bytes
    int bytes;

    //Declare the structure of the sending message in order
    //the filemanager to communicate with the client and vice versa
    FILEHEADER *msg = (FILEHEADER *)malloc(sizeof(FILEHEADER));


    //While the client is connect to the system you have to keep the connection
    while(1)
    {
        //If connection is established then start communicating //
        //Initialize buffer with zeros //
        bzero(buf, sizeof(buf));
        //Waiting...to receive data from the client//
        if (recv(acptsock, buf, sizeof(buf), 0) < 0)
        {
            perror("Received() failed!");
            close(acptsock);
            pthread_exit((void *) 0);
        }

        //Check if direc received a message
        if(strlen(buf) != 0)
        {
            //Show the message that received//
            printf("----------------------------------\n");
            printf("accept_thread received: %s\n", buf);
        }
        else if (strlen(buf) == 0)
        {
            //printf("Unable to received messsage!\n");
            close(acptsock);
            pthread_exit((void *) 0);
        }

        //Decode the message that receive from the client
        //in order to identify the type of the message//
        decode(buf,msg);

        if( strcmp(msg->type , "REQCLIENTID" )== 0)
        {
            bzero(buf,sizeof(buf));
            //encode the clientID
            sprintf(buf,"REQCLIENTID,%ld,%ld" , registerClient(msg->username ), msg->MSGID );
            if (send(acptsock, buf, sizeof(buf) , 0) < 0 )
            {
                perror("Send:Unable to send clientID");
            }

            //Deallocations
            free(msg->username);
        }


        else if( strcmp(msg->type , "REQCREATE" )== 0 )
        {
            printf("Received Create: %s , owner:%ld\n", msg->filename, msg->owner);

            //Store fileid
            unsigned long fileid = lookUpFileID(msg->filename , msg->owner );

            if(fileid == -1)
            {
                //Store the new file in the metadata
                //Also , retrieve the fileID for the file
                fileid = registerFile(msg->filename, msg->owner);
            }

            printf("REQCREATE Function return: %ld \n", fileid);

            bzero(buf, sizeof(buf));
            //encode the clientID
            sprintf(buf, "REQCREATE,%ld,%ld", fileid, msg->MSGID);
            if (send(acptsock, buf, sizeof(buf), 0) < 0)
            {
                perror("Send:Unable to send clientID");
            }
            //Deallocations
            free(msg->filename);

        }
        else if( strcmp(msg->type , "REQFILEID" )== 0 )
        {
            printf("Received REQFILEID: %s , owner:%ld\n" , msg->filename ,msg->owner);

            //Store the new file in the metadata
            //Also , retrieve the fileID for the file
            unsigned long fileid = lookUpFileID(msg->filename , msg->owner );

            if(fileid == -1)
            {
                //Store the new file in the metadata
                //Also , retrieve the fileID for the file
                fileid = registerFile(msg->filename, msg->owner);
            }

            printf("REQFILEID Function return: %ld \n" , fileid);

            bzero(buf,sizeof(buf));
            //encode the clientID
            sprintf(buf,"REQFILEID,%ld,%ld" , fileid , msg->MSGID );
            if (send(acptsock, buf, sizeof(buf) , 0) < 0 )
            {
                perror("Send:Unable to send clientID");
            }

            //Deallocations
            free(msg->filename);
        }
        else if( strcmp(msg->type , "REQFILESLIST" )== 0 )
        {
            bzero(buf,sizeof(buf));

            GString *list=NULL;

            list=getfilelist(list);
            printf("List\n");

            if (send(acptsock, list->str, strlen(list->str) , 0) < 0 )
            {
                perror("Send:Unable to send clientID");
            }

            //Deallocate memory
            g_string_free(list,TRUE);

        }


    }//While
}
コード例 #19
0
ファイル: client.c プロジェクト: FreshXOpenSource/wallyd
//  Loop the client thread here
void *wallyClientThread(void *argPtr){
   slog(DEBUG,DEBUG,"WallyClient Thread started. Waiting for plugins to get ready.");
   pthread_mutex_init(&commandMutex,0);
   while(ph->pluginLoaderDone == false){
      usleep(100);
   }
   slog(DEBUG,FULLDEBUG,"WallyClient Thread started. Plugins ready.");
   commandMap = malloc(sizeof(hash_table));
   ht_init(commandMap, HT_KEY_CONST | HT_VALUE_CONST, 0.05);
   tempMap = malloc(sizeof(hash_table));
   ht_init(tempMap, HT_KEY_CONST | HT_VALUE_CONST, 0.05);

   int startDelay = 1;
   int ret=0;
   char *startDelayString = NULL;

   clientThreadRunning = true;

   while(clientThreadRunning == true) {
       switch(clientState)
           {
              case DISCOVERY:
                  //ssdpDiscovery(1);
                  //    Both plugins (ssdp and cloudConnector) 
                  //    set ph->location and return once they registered
                  //    Cloud connector needs additional handling after
                asprintf(&startDelayString,"%d",startDelay);
                if(ph->ssdp) {
                      call("ssdp::discovery",&ret,startDelayString);
                } else if(ph->cloud) {
                      call("cloud::connect",&ret,startDelayString);
                }
                free(startDelayString);
                if(ph->location) {
                     if(run_callback){
                        slog(DEBUG,DEBUG,"Executing JS Callback for client discovery");
#ifndef WITH_SEADUK
                        duv_push_ref(ctx, finishCallback);
                        duk_push_string(ctx, ph->location);
                        duk_call(ctx, 1);
                        duk_to_int(ctx, -1);
#endif
                     }
                     saveLocation(FLAGFILE);
                  }
                  startDelay = 1;
                  slog(DEBUG,DEBUG,"Change state from discovery to register");
                  clientState = REGISTER;
                  break;
              case REGISTER:
                  if(ph->location){
                     if(registerClient(ph->location)){
                        slog(DEBUG,DEBUG,"Starting longpoll."); 
                        url_longpoll(commandURL,60,LONGPOLL_INIT,NULL);
                        clientState = COMMAND;
                     } else {
                        slog(DEBUG,DEBUG,"Registration failed."); 
                     }
                  } else {
                     slog(LVL_INFO,WARN,"Register was called without a valid location");
                  }
                  break;
              case COMMAND:
                  slog(DEBUG,DEBUG,"Requesting next core command from %s",commandURL);
                  int ret = getCommand(commandURL,60);
                  if(ret == true && ht_get_simple(commandMap,"command")){
                     int commandValid = false;
                     slog(DEBUG,DEBUG,"Command : %s",ht_get_simple(commandMap,"command"));
                     // Handle the commands which are supported by the wallyd here
                     if(ht_compare(commandMap,"command","config")){
                           commandValid = true;
                           slog(DEBUG,DEBUG,"Preparing to persist config");
                           if(persistConfig(registerMap)){
                              sendSuccess(ht_get_simple(commandMap,"id"));
                           }
                     }
                     if(ht_compare(commandMap,"command","reboot")){
                           commandValid = true;
                           sendSuccess(ht_get_simple(commandMap,"id"));
                           slog(DEBUG,DEBUG,"Preparing to reboot");
                           system(BIN_REBOOT);
                     }
                     if(ht_compare(commandMap,"command","firmwareUpdate")){
                           commandValid = true;
                           sendSuccess(ht_get_simple(commandMap,"id"));
                           slog(DEBUG,DEBUG,"Preparing to update firmware");
                           system(BIN_UPDATEFW);
                     }
                     if(ht_compare(commandMap,"command","getlog")){
                           commandValid = true;
                           slog(DEBUG,DEBUG,"Preparing to send log to server");
                           //sendSuccess(ht_get_simple(commandMap,"id"));
                           //persistConfig(registerMap);
                     }
                     if(commandValid == false){
                           slog(DEBUG,DEBUG,"Command %s not valid. Ingoring.",ht_get_simple(commandMap,"command"));
                           sendFailed(ht_get_simple(commandMap,"id"),"unknown.command");
                     }
                  } else {
                     slog(LVL_INFO,WARN,"getCommand failed.");
                  }
                  pthread_mutex_unlock(&commandMutex);
                  break;
              case QUIT:
                  slog(DEBUG,DEBUG,"Thread is quiting.");
                  break;
           }
       sleep(threadDelay);
   }
   return 0;
}
コード例 #20
0
/*
	Main
*/
int main(int argc, char ** argv)
{
	struct sockaddr_in	inaddr;
	socklen_t		inaddrlen;
	struct timeval	timeout;
	ssl_t			*ssl;
	serverDtls_t	*dtlsCtx;
	SOCKET			sock;
	fd_set			readfd;
	unsigned char	*sslBuf, *recvfromBuf, *CAstream;
#ifdef USE_DTLS_DEBUG_TRACE	
	unsigned char   *addrstr;
#endif
#if !defined(ID_PSK) && !defined(ID_DHE_PSK)
	unsigned char   *keyValue, *certValue;
	int32           keyLen, certLen;
#endif	
	sslKeys_t		*keys;
	int32			freeBufLen, rc, val, recvLen, err, CAstreamLen;
	int32			sslBufLen, rcr, rcs, sendLen, recvfromBufLen;
	sslSessOpts_t	options;

#ifdef WIN32
	WSADATA         wsaData;
	WSAStartup(MAKEWORD(1, 1), &wsaData);
#endif

	rc = 0;
	ssl = NULL;
	dtlsCtx = NULL;
	sock = INVALID_SOCKET;

	/* parse input arguments */
	if (0 != process_cmd_options(argc, argv)) {
		usage();
		return 0;
	}

	if (sigsetup() < 0) {
		_psTrace("Init error creating signal handlers\n");
		return DTLS_FATAL;
	}

	if (matrixSslOpen() < 0) {
		_psTrace("Init error opening MatrixDTLS library\n");
		return DTLS_FATAL;
	}
	if (matrixSslNewKeys(&keys, NULL) < 0) {
		_psTrace("Init error allocating key structure\n");
		matrixSslClose();
		return DTLS_FATAL;
	}

	if ((rc = initClientList(MAX_CLIENTS)) < 0) {
		_psTrace("Init error opening client list\n");
		goto MATRIX_EXIT;
	}

	recvfromBufLen = matrixDtlsGetPmtu();
	if ((recvfromBuf = psMalloc(MATRIX_NO_POOL, recvfromBufLen)) == NULL) {
		rc = PS_MEM_FAIL;
		_psTrace("Init error allocating receive buffer\n");
		goto CLIENT_EXIT;
	}

#ifdef USE_HEADER_KEYS
/*
	In-memory based keys
	Build the CA list first for potential client auth usage
*/
	CAstreamLen = 0;
#ifdef USE_RSA
	CAstreamLen += sizeof(RSACAS);
#ifdef USE_ECC
	CAstreamLen += sizeof(ECDHRSACAS);
#endif
#endif
#ifdef USE_ECC
	CAstreamLen += sizeof(ECCAS);
#endif
	CAstream = psMalloc(NULL, CAstreamLen);

	CAstreamLen = 0;
#ifdef USE_RSA
	memcpy(CAstream, RSACAS, sizeof(RSACAS));
	CAstreamLen += sizeof(RSACAS);
#ifdef USE_ECC
	memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
	CAstreamLen += sizeof(ECDHRSACAS);
#endif
#endif
#ifdef USE_ECC
	memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
	CAstreamLen += sizeof(ECCAS);
#endif

#ifdef EXAMPLE_RSA_KEYS
	switch (g_rsaKeySize) {
		case 1024:
			certValue = (unsigned char *)RSA1024;
			certLen = sizeof(RSA1024);
			keyValue = (unsigned char *)RSA1024KEY;
			keyLen = sizeof(RSA1024KEY);
			break;
		case 2048:
			certValue = (unsigned char *)RSA2048;
			certLen = sizeof(RSA2048);
			keyValue = (unsigned char *)RSA2048KEY;
			keyLen = sizeof(RSA2048KEY);
			break;
		case 3072:
			certValue = (unsigned char *)RSA3072;
			certLen = sizeof(RSA3072);
			keyValue = (unsigned char *)RSA3072KEY;
			keyLen = sizeof(RSA3072KEY);
			break;
		case 4096:
			certValue = (unsigned char *)RSA4096;
			certLen = sizeof(RSA4096);
			keyValue = (unsigned char *)RSA4096KEY;
			keyLen = sizeof(RSA4096KEY);
			break;
		default:
			_psTraceInt("Invalid RSA key length (%d)\n", g_rsaKeySize);
			return -1;
	}

	if ((rc = matrixSslLoadRsaKeysMem(keys, (const unsigned char *)certValue,
			certLen, (const unsigned char *)keyValue, keyLen, CAstream,
			CAstreamLen)) < 0) {
		_psTrace("No certificate material loaded.  Exiting\n");
		psFree(CAstream, NULL);
		matrixSslDeleteKeys(keys);
		matrixSslClose();
		return rc;
	}
#endif


#ifdef EXAMPLE_ECDH_RSA_KEYS
	switch (g_ecdhKeySize) {
		case 256:
			certValue = (unsigned char *)ECDHRSA256;
			certLen = sizeof(ECDHRSA256);
			keyValue = (unsigned char *)ECDHRSA256KEY;
			keyLen = sizeof(ECDHRSA256KEY);
			break;
		case 521:
			certValue = (unsigned char *)ECDHRSA521;
			certLen = sizeof(ECDHRSA521);
			keyValue = (unsigned char *)ECDHRSA521KEY;
			keyLen = sizeof(ECDHRSA521KEY);
			break;
		default:
			_psTraceInt("Invalid ECDH_RSA key length (%d)\n", g_ecdhKeySize);
			return -1;
	}

	if ((rc = matrixSslLoadEcKeysMem(keys, (const unsigned char *)certValue,
				certLen, (const unsigned char *)keyValue, keyLen, CAstream,
				CAstreamLen)) < 0) {
		_psTrace("No certificate material loaded.  Exiting\n");
		psFree(CAstream, NULL);
		matrixSslDeleteKeys(keys);
		matrixSslClose();
		return rc;
	}
#endif

#ifdef EXAMPLE_EC_KEYS
	switch (g_eccKeySize) {
		case 192:
			certValue = (unsigned char *)EC192;
			certLen = sizeof(EC192);
			keyValue = (unsigned char *)EC192KEY;
			keyLen = sizeof(EC192KEY);
			break;
		case 224:
			certValue = (unsigned char *)EC224;
			certLen = sizeof(EC224);
			keyValue = (unsigned char *)EC224KEY;
			keyLen = sizeof(EC224KEY);
			break;
		case 256:
			certValue = (unsigned char *)EC256;
			certLen = sizeof(EC256);
			keyValue = (unsigned char *)EC256KEY;
			keyLen = sizeof(EC256KEY);
			break;
		case 384:
			certValue = (unsigned char *)EC384;
			certLen = sizeof(EC384);
			keyValue = (unsigned char *)EC384KEY;
			keyLen = sizeof(EC384KEY);
			break;
		case 521:
			certValue = (unsigned char *)EC521;
			certLen = sizeof(EC521);
			keyValue = (unsigned char *)EC521KEY;
			keyLen = sizeof(EC521KEY);
			break;
		default:
			_psTraceInt("Invalid ECC key length (%d)\n", g_eccKeySize);
			return -1;
	}

	if ((rc = matrixSslLoadEcKeysMem(keys, certValue, certLen,
			keyValue, keyLen, CAstream, CAstreamLen)) < 0) {
		_psTrace("No certificate material loaded.  Exiting\n");
		psFree(CAstream, NULL);
		matrixSslDeleteKeys(keys);
		matrixSslClose();
		return rc;
	}
#endif

#ifdef REQUIRE_DH_PARAMS
	if (matrixSslLoadDhParamsMem(keys, DHPARAM2048, DHPARAM2048_SIZE)
			< 0) {
		_psTrace("Unable to load DH parameters\n");
	}
#endif /* DH_PARAMS */


	psFree(CAstream, NULL);
#else /* USE_HEADER_KEYS */
/*
	File based keys
	Build the CA list first for potential client auth usage
*/
	CAstreamLen = 0;
#ifdef USE_RSA
	if (g_rsaKeySize == 3072)
		CAstreamLen += (int32)strlen(rsaCA3072File) + 1;
	else
		CAstreamLen += (int32)strlen(rsaCAFile) + 1;
#ifdef USE_ECC
	CAstreamLen += (int32)strlen(ecdhRsaCAFile) + 1;
#endif
#endif
#ifdef USE_ECC
	CAstreamLen += (int32)strlen(ecCAFile) + 1;
#endif
	CAstream = psMalloc(NULL, CAstreamLen);
	memset(CAstream, 0x0, CAstreamLen);

	CAstreamLen = 0;
#ifdef USE_RSA
	if (g_rsaKeySize == 3072) {
		memcpy(CAstream, rsaCA3072File,	strlen(rsaCA3072File));
		CAstreamLen += strlen(rsaCA3072File);
	}
	else {
		memcpy(CAstream, rsaCAFile,	strlen(rsaCAFile));
		CAstreamLen += strlen(rsaCAFile);
	}
#ifdef USE_ECC
	memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
	memcpy(CAstream + CAstreamLen, ecdhRsaCAFile,  strlen(ecdhRsaCAFile));
	CAstreamLen += strlen(ecdhRsaCAFile);
#endif
#endif
#ifdef USE_ECC
	if (CAstreamLen > 0) {
		memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
	}
	memcpy(CAstream + CAstreamLen, ecCAFile,  strlen(ecCAFile));
#endif

/* Load Identiy */
#ifdef EXAMPLE_RSA_KEYS
	if ((rc = matrixSslLoadRsaKeys(keys, rsaCertFile, rsaPrivkeyFile, NULL,
			(char*)CAstream)) < 0) {
		_psTrace("No certificate material loaded.  Exiting\n");
		psFree(CAstream);
		matrixSslDeleteKeys(keys);
		matrixSslClose();
		return rc;
	}
#endif


#ifdef EXAMPLE_ECDH_RSA_KEYS
	if ((rc = matrixSslLoadEcKeys(keys, ecdhRsaCertFile, ecdhRsaPrivkeyFile,
			NULL, (char*)CAstream)) < 0) {
		_psTrace("No certificate material loaded.  Exiting\n");
		psFree(CAstream);
		matrixSslDeleteKeys(keys);
		matrixSslClose();
		return rc;
	}
#endif

#ifdef EXAMPLE_EC_KEYS
	if ((rc = matrixSslLoadEcKeys(keys, ecCertFile, ecPrivkeyFile, NULL,
			(char*)CAstream)) < 0) {
		_psTrace("No certificate material loaded.  Exiting\n");
		psFree(CAstream);
		matrixSslDeleteKeys(keys);
		matrixSslClose();
		return rc;
	}
#endif

#ifdef REQUIRE_DH_PARAMS
	if (matrixSslLoadDhParams(keys, dhParamFile) < 0) {
		_psTrace("Unable to load DH parameters\n");
	}
#endif


	psFree(CAstream);
#endif /* USE_HEADER_KEYS */


#ifdef USE_PSK_CIPHER_SUITE
	/* The first ID is considered as null-terminiated string for
	   compatibility with OpenSSL's s_client default client identity
	   "Client_identity" */

 	matrixSslLoadPsk(keys,
            	PSK_HEADER_TABLE[0].key,
            	sizeof(PSK_HEADER_TABLE[0].key),
            	PSK_HEADER_TABLE[0].id,
            	strlen((const char *)PSK_HEADER_TABLE[0].id));

	for (rc = 1; rc < PSK_HEADER_TABLE_COUNT; rc++) {
        matrixSslLoadPsk(keys,
            	PSK_HEADER_TABLE[rc].key,
            	sizeof(PSK_HEADER_TABLE[rc].key),
            	PSK_HEADER_TABLE[rc].id,
            	sizeof(PSK_HEADER_TABLE[rc].id));
    }
#endif /* PSK */


	if ((sock = newUdpSocket(NULL, DTLS_PORT, &err)) == INVALID_SOCKET) {
		_psTrace("Error creating UDP socket\n");
		goto DTLS_EXIT;
	}
	_psTraceInt("DTLS server running on port %d\n", DTLS_PORT);

/*
	Server loop
*/
	for (exitFlag = 0; exitFlag == 0;) {
		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		FD_ZERO(&readfd);
		FD_SET(sock, &readfd);
/*
		Always just wait a second for any incoming data.  The primary loop
		mechanism reads data from one source and replies with handshake data
		if needed (that reply may be a resend if reading a repeat message).
		Individual client timeouts are then handled
*/
		val = select(sock+1, &readfd, NULL, NULL, &timeout);

		if (val > 0 && FD_ISSET(sock, &readfd)) {
			psTraceIntDtls("Select woke %d\n", val);
			/* recvfrom data must always go into generic buffer becuase we
			don't yet know who it is from */
			inaddrlen = sizeof(struct sockaddr_in);
			if ((recvLen = (int32)recvfrom(sock, recvfromBuf, recvfromBufLen, 0,
										   (struct sockaddr *)&inaddr, &inaddrlen)) < 0) {
#ifdef WIN32
				if (SOCKET_ERRNO != EWOULDBLOCK &&
						SOCKET_ERRNO != WSAECONNRESET) {
#else
				if (SOCKET_ERRNO != EWOULDBLOCK) {
#endif
					_psTraceInt("recvfrom error %d.  Exiting\n", SOCKET_ERRNO);
					goto DTLS_EXIT;
				}
				continue;
				}
#ifdef USE_DTLS_DEBUG_TRACE
			/* nice for debugging */
			{
				const char *addrstr;
				addrstr = getaddrstring((struct sockaddr *)&inaddr, 1);
				psTraceIntDtls("Read %d bytes ", recvLen);
				psTraceStrDtls("from %s\n", (char*)addrstr);
				psFree(addrstr, NULL);
			}
#endif

			/* Locate the SSL context of this receive and create a new session
			if not found */
			if ((dtlsCtx = findClient(inaddr)) == NULL) {
				memset(&options, 0x0, sizeof(sslSessOpts_t));
				options.versionFlag = SSL_FLAGS_DTLS;
				options.truncHmac = -1;

				if (matrixSslNewServerSession(&ssl, keys,
						certValidator, &options) < 0) {
					rc = DTLS_FATAL; goto DTLS_EXIT;
				}
				if ((dtlsCtx = registerClient(inaddr, sock, ssl)) == NULL) {
					/* Client list is full.  Just have to ignore */
					matrixSslDeleteSession(ssl);
					continue;
				}
			}

			ssl = dtlsCtx->ssl;
			/*  Move socket data into internal buffer */
			freeBufLen = matrixSslGetReadbuf(ssl, &sslBuf);
			psAssert(freeBufLen >= recvLen);
			psAssert(freeBufLen == matrixDtlsGetPmtu());
			memcpy(sslBuf, recvfromBuf, recvLen);

			/*	Notify SSL state machine that we've received more data into the
			ssl buffer retreived with matrixSslGetReadbuf. */
			if ((rcr = matrixSslReceivedData(ssl, recvLen, &sslBuf,
					(uint32*)&freeBufLen)) < 0) {
				clearClient(dtlsCtx);
				continue;	/* Next connection */
			}
			/* Update last activity time and reset timeout*/
			psGetTime(&dtlsCtx->lastRecvTime, NULL);
			dtlsCtx->timeout = MIN_WAIT_SECS;

PROCESS_MORE_FROM_BUFFER:
			/* Process any incoming plaintext application data */
			switch (rcr) {
				case MATRIXSSL_HANDSHAKE_COMPLETE:
					/* This is a resumed handshake case which means we are
					the last to receive handshake flights and we know the
					handshake is complete.  However, the internal workings
					will not flag us officially complete until we receive
					application data from the peer so we need a local flag
					to handle this case so we are not resending our final
					flight */
					dtlsCtx->connStatus = RESUMED_HANDSHAKE_COMPLETE;
					psTraceDtls("Got HANDSHAKE_COMPLETE out of ReceivedData\n");
					break;
				case MATRIXSSL_APP_DATA:
					/* Now safe to clear the connStatus flag that was keeping
					track of the state between receiving the final flight of
					a resumed handshake and receiving application data.  The
					reciept of app data has now internally disabled flight
					resends */
					dtlsCtx->connStatus = 0;
					_psTrace("Client connected.  Received...\n");
					_psTraceStr("%s\n", (char*)sslBuf);
					break;
				case MATRIXSSL_REQUEST_SEND:
					/* Still handshaking with this particular client */
					while ((sslBufLen = matrixDtlsGetOutdata(ssl,
							&sslBuf)) > 0) {
						if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
											   (struct sockaddr*)&inaddr,
											   sizeof(struct sockaddr_in),
											   dtlsCtx->timeout,
											   packet_loss_prob,
											   NULL)) < 0) {
							psTraceDtls("udpSend error.  Ignoring\n");
						}
						/* Always indicate the entire datagram was sent as
						there is no way for DTLS to handle partial records.
						Resends and timeouts will handle any problems */
						rcs = matrixDtlsSentData(ssl, sslBufLen);

						if (rcs == MATRIXSSL_REQUEST_CLOSE) {
							psTraceDtls("Got REQUEST_CLOSE out of SentData\n");
							clearClient(dtlsCtx);
							break;
						}
						if (rcs == MATRIXSSL_HANDSHAKE_COMPLETE) {
							/* This is the standard handshake case */
							_psTrace("Got HANDSHAKE_COMPLETE from SentData\n");
							break;
						}
						/* SSL_REQUEST_SEND is handled by loop logic */
					}
					break;
				case MATRIXSSL_REQUEST_RECV:
					psTraceDtls("Got REQUEST_RECV from ReceivedData\n");
					break;
				case MATRIXSSL_RECEIVED_ALERT:
					/* The first byte of the buffer is the level */
					/* The second byte is the description */
					if (*sslBuf == SSL_ALERT_LEVEL_FATAL) {
						psTraceIntDtls("Fatal alert: %d, closing connection.\n",
									*(sslBuf + 1));
						clearClient(dtlsCtx);
						continue; /* Next connection */
					}
					/* Closure alert is normal (and best) way to close */
					if (*(sslBuf + 1) == SSL_ALERT_CLOSE_NOTIFY) {
						clearClient(dtlsCtx);
						continue; /* Next connection */
					}
					psTraceIntDtls("Warning alert: %d\n", *(sslBuf + 1));
					if ((rcr = matrixSslProcessedData(ssl, &sslBuf,
							(uint32*)&freeBufLen)) == 0) {
						continue;
					}
					goto PROCESS_MORE_FROM_BUFFER;

				default:
					continue; /* Next connection */
			}
		} else if (val < 0) {
			if (SOCKET_ERRNO != EINTR) {
				psTraceIntDtls("unhandled error %d from select", SOCKET_ERRNO);
			}
		}
/*
		Have either timed out waiting for a read or have processed a single
		recv.  Now check to see if any timeout resends are required
*/
		rc = handleResends(sock);
	}	/* Main Select Loop */


DTLS_EXIT:
	psFree(recvfromBuf, NULL);
CLIENT_EXIT:
	closeClientList();
MATRIX_EXIT:
	matrixSslDeleteKeys(keys);
	matrixSslClose();
	if (sock != INVALID_SOCKET) close(sock);
	return rc;
}

/******************************************************************************/
/*
	Work through client list and resend handshake flight if haven't heard
	from them in a while
*/
static int32 handleResends(SOCKET sock)
{
	serverDtls_t	*dtlsCtx;
	ssl_t			*ssl;
	psTime_t		now;
	unsigned char	*sslBuf;
	int16			i;
	int32			sendLen, rc;
	uint32			timeout, sslBufLen, clientCount;

	clientCount = 0; /* return code is number of active clients or < 0 on error */
	psGetTime(&now, NULL);
	for (i = 0; i < tableSize; i++) {
		dtlsCtx = &clientTable[i];
		if (dtlsCtx->ssl != NULL) {
			clientCount++;
			timeout = psDiffMsecs(dtlsCtx->lastRecvTime, now, NULL) / 1000;
			/* Haven't heard from this client in a while.  Might need resend */
			if (timeout > dtlsCtx->timeout) {
				/* if timeout is too great. clear conn */
				if (dtlsCtx->timeout >= MAX_WAIT_SECS) {
					clearClient(dtlsCtx);
					clientCount--;
					break;
				}
				/* Increase the timeout for next pass */
				dtlsCtx->timeout *= 2;

				/* If we are in a RESUMED_HANDSHAKE_COMPLETE state that means
				we are positive the handshake is complete so we don't want to
				resend no matter what.  This is an interim state before the
				internal mechaism sees an application data record and flags
				us as complete officially */
				if (dtlsCtx->connStatus == RESUMED_HANDSHAKE_COMPLETE) {
					psTraceDtls("Connected but awaiting data\n");
					continue;
				}
				ssl = dtlsCtx->ssl;
				while ((sslBufLen = matrixDtlsGetOutdata(ssl,
						&sslBuf)) > 0) {
					if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
										   (struct sockaddr*)&dtlsCtx->addr,
										   sizeof(struct sockaddr_in),
										   dtlsCtx->timeout / 2,
										   packet_loss_prob,
										   NULL)) < 0) {
						psTraceDtls("udpSend error.  Ignoring\n");
					}
					/* Always indicate the entire datagram was sent as
					there is no way for DTLS to handle partial records.
					Resends and timeouts will handle any problems */
					if ((rc = matrixDtlsSentData(ssl, sslBufLen)) < 0) {
						psTraceDtls("internal error\n");
						clearClient(dtlsCtx);
						clientCount--;
						break;
					}
					if (rc == MATRIXSSL_REQUEST_CLOSE) {
						psTraceDtls("Got REQUEST_CLOSE out of SentData\n");
						clearClient(dtlsCtx);
						clientCount--;
						break;
					}
					if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) {
						/* This is the standard handshake case */
						psTraceDtls("Got HANDSHAKE_COMPLETE out of SentData\n");
						break;
					}
					/* SSL_REQUEST_SEND is handled by loop logic */
				}

			}
		}
	}
	return clientCount;
}
コード例 #21
0
ファイル: server_PFS.c プロジェクト: ashishbedi/netsys
int main ( int argc, char * argv[ ] ) {
  int sock, nuSock;          // This will be our sockets
  int nbytes;                // Number of bytes we receive in our message
  int code;                  // Error code for Select
  char buffer[ MAXBUFSIZE ]; // A buffer to store our received message
  char msg[ MAXBUFSIZE ];    // A Message to return
  Repository repo;           // The registration list
  fd_set fds;
  struct timeval timeout;
  int count = 0;

  //
  // Make sure port is given on command line
  // 
  if ( argc != 2 ) {
	printf( "USAGE:  <port>\n" );
	exit( EXIT_FAILURE );
  }

  //
  // Initialize all the things!
  //
  repo.total = 0;
  maxPrint( &repo );
  sock = createSocket( atoi( argv[1] ) );

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

  FD_ZERO( &fds );
  FD_SET( sock, &fds );
  nuSock = acceptConnection( sock );
  ERROR( nuSock < 0 );
  FD_SET( nuSock, &fds );
  
  //
  // Enter command loop
  //
  for ( ; ; ) {
	/*	if ( ( code = select( sizeof( fds )*8, &fds, NULL, NULL, &timeout ) ) < 0 ) {
	  ERROR( code < 0 );
	}
	else if ( code == 0 ) {
	  printf( "$ Timeout [%i]\r", count = ++count % 100 );
	  ERROR( count );
	}
	else {
	  count = 0;
	  if ( FD_ISSET( sock, &fds ) ) {
		// Loop through all the conenctions Available
		while ( ( nuSock = acceptConnection( sock ) ) > 0 );
		FD_SET( nuSock, &fds );
	  }
	*/	  
	ERROR( nuSock < 0 );
	bzero( buffer, MAXBUFSIZE );
	nbytes = read( nuSock, buffer, MAXBUFSIZE );
	ERROR( nbytes < 0 );
	printf( "[%s] %s\n", repo.cxn[whoisthis( &repo, nuSock )].name, buffer );
	
	switch ( parseCmd ( buffer ) ) 
	  {
	  case CONNECT:
		{
		  nbytes = write( nuSock, buffer, MAXBUFSIZE );
		  ERROR( nbytes < 0 );
		  switch( registerClient( &repo, nuSock ) ) 
			{
			case SUCCESS:
			  getList ( &repo, nuSock );
			  printf( "> Success in registering '%s'\n", repo.cxn[repo.total-1].name );
			  break;
			case FAILURE:
			  printf( "> Error in registration\n" );
			  break;
			}
		  break;
		}
	  case GET:
		sendMaster( &repo, nuSock );
		break;
	  case EXIT:
		{
		  switch( removeClient( &repo, nuSock ) ) {
		  case SUCCESS: 
			printf( "> Client has been removed.\n" );
			break;
		  case FAILURE:
			printf( "> Error removing client.\n" );
			break;
		  }
		  break;
		}
	  default: 
		sprintf( msg, "Invalid command: '%s'", buffer); 
		nbytes = write( nuSock, msg, MAXBUFSIZE );
		ERROR( nbytes < 0 );
		break;
	  }
  }
  
  close( nuSock );
  close( sock );
  
  return EXIT_SUCCESS;
} // main( )
コード例 #22
0
ファイル: client.c プロジェクト: julianborrey/bashChatClient
int main(int argc, char* argv[]){
   printf("\n" BAR " Running Chat Client %s. " BAR "\n\n", argv[1]);
   
   if(argc != 2){
      printf("ERROR: You must enter 1 name (no spaces) on the command line.\n");
      return EXIT_FAILURE;
   }
   
   int cliPort = getPortFromName(argv[1]); //get the client's port based on name

   printf("Setting up client for UDP... \n");
   int UDPsocket = getUDPSocket(); //obtain socket for UDP

   struct sockaddr_in cliAddr;
   setCliAddr(cliPort, UDPsocket, &cliAddr); //set up clients address with port
   
   struct sockaddr_in servAddr; //this is the server's address
   setServAddr(&servAddr);      //set up the server addrss
   
   /************************* Contact  UDP Server **********************/
   
   char sendBuf[BUF_SIZE];
   memset(&sendBuf, 0, BUF_SIZE);
   char recvBuf[BUF_SIZE];
   memset(&recvBuf, 0, BUF_SIZE);
   int addrLen = sizeof(servAddr);
   char currChar;
   
   bool using = true; //when using the program
   while(using){

      //register with UDP server
      registerClient(UDPsocket, argv[1], (struct sockaddr*) &servAddr, sendBuf);
      //now we expect to get a response which is a list of people
         
      //this linked list is the register of who is an isn't connected
      CC reg = (CC) malloc(sizeof(struct ConnectedClient)); //acts as head
      strcpy(reg->name, "CLIENT LIST");
      reg->next = NULL;
      
      //obtain and display list of clients from UDP server
      getClientList(reg, UDPsocket, recvBuf);

      /********************** TRANSITION TO TCP *********************************/
      
      printf("Would you like to wait for a connection or make a connection? (w/m): ");
      char waitOrMake = getc(stdin); 
      
      //get a new socket of TCP type
      int sockTCP = socket(AF_INET, SOCK_STREAM, 0);
      if(sockTCP < 0){ //if < 0 we have an error
         deRegister(UDPsocket, argv[1], (struct sockaddr*) &servAddr, sendBuf);
         perror("We have an error");
         return EXIT_FAILURE;
      }
      
      struct sockaddr_in tcpAddr = cliAddr;
      tcpAddr.sin_port = htons(ntohs(cliAddr.sin_port) + 1); //TCP port will be UDPport++;
      
      int nowSocket; //this will be the socket we use to communicate
      //may come from accepting a connection or starting a connection
      
      //we are now going to make a connection
      char* connectee = NULL; //the name of the person we connect to
      if(waitOrMake == 'm'){ //if the client wants to make a connection
         printf("Pick the numbered client you wish to talk to: ");
         int clientNum = 0;
         scanf("%d", &clientNum);
         
         //get address of other client
         struct sockaddr_in* cliOfInterest = getAddr(reg, clientNum);
         
         connectee = getName(reg, cliOfInterest);
         printf("Making connection to %s\n", connectee);
         //make connection to other client
         printf("Trying connection to socket %d\n", ntohs(cliOfInterest->sin_port));
         if(connect(sockTCP, (struct sockaddr*) cliOfInterest, sizeof(*cliOfInterest)) < 0){
            deRegister(UDPsocket, argv[1], (struct sockaddr*) &servAddr, sendBuf);         
            perror("We have an error");
            return EXIT_FAILURE;
         }
         
         nowSocket = sockTCP;
         printf("Connection made!\n");
         
         //notify conectee that I connected
         sprintf(sendBuf, "%s%s%s %s%s", CONN_FANFAIR, "\t\t", argv[1], 
                 CONN_NOTICE, CONN_FANFAIR);
         send(nowSocket, sendBuf, strlen(sendBuf), 0);
      } else {
         int currCliSocket; //this will be the socket we recieve a connection on  
         struct sockaddr_in cliOfInterest;
         int len = sizeof(cliOfInterest);
         
         //bind the TCP address (different port) to the TCP socket
         bind(sockTCP, (struct sockaddr*) &tcpAddr, sizeof(tcpAddr));
         printf("Now listening on port %d.\n", ntohs(tcpAddr.sin_port));
         listen(sockTCP, 1); //being listening for connections

         //if we get a connection we record the socket we are using and the address
         currCliSocket = accept(sockTCP, (struct sockaddr*) &cliOfInterest, &len);
         
         if(currCliSocket >= 0){
            nowSocket = currCliSocket;
            printf("Connection being made by another client ...\n");
            //name is send over TCP by client
         } else {
            deRegister(UDPsocket, argv[1], (struct sockaddr*) &servAddr, sendBuf);
            perror("Incomming connection failed");
            return EXIT_FAILURE;
         }
      }
      
      //at this point we have a TCP connection with another client
      //we are now going to run two threads simultaneously
      //the child thread will be to send chat
      //the parent thread will be to listen and display
      
      //spawn a child process
      int pid = fork();
      if(pid < 0){ //if failed to fork
         deRegister(UDPsocket, argv[1], (struct sockaddr*) &servAddr, sendBuf);
         perror("Failed to fork!\n");
         return EXIT_FAILURE;
      } else if(pid != 0) { /*********************** PARENT *****************/      
         printf("You are now in a chat room.\n"
                "Type \"" END_CONN "\" to exit the chat room.\n\n");
         
         bool sending = true;   //client still wants to chat
         bool firstTime = true; //start off first time
         while(sending){ //we will be ready to send until END_CONN
            //printf("You [%s]: ", timeStr());
            printf("%s", KCYN); //make home client cyan
            memset(&sendBuf, 0, BUF_SIZE); //clear buffer
            
            if(firstTime){             //if just come from selection
               firstTime = false;      //next time will not be first time
               currChar = getc(stdin); //we do another getc() to clear ENTER_KEY
            }
            
            currChar = getc(stdin);        //get message to send
            
            int i = 0;
            //while we done hit enter and less than max buff (-1 for '\0')
            while(((int)currChar != ENTER_KEY) && (i < (BUF_SIZE - 2))){
               sendBuf[i] = currChar;
               i++;
               currChar = getc(stdin);
            }
            sendBuf[i] = '\0';
            
            //if typed in command to end client, end client
            if(strcmp(sendBuf, END_CONN) == 0){
               sending = false; //end the chat room

               //send message of leaving chatroom
               send(nowSocket, LEAVING_CHATROOM_MSG, sizeof(LEAVING_CHATROOM_MSG), 0); 
               kill(pid, SIGKILL); //kill child process
            } else { //send message to server
               send(nowSocket, sendBuf, BUF_SIZE, 0);
            }
         }
      
      } else { /*********************************** CHILD **************************/
         int nread;
         char bufbuf[120];
         while(true){ //always ready to receive chat --------> until shared memory
            memset(recvBuf, 0, BUF_SIZE); //clear buffer
            nread = read(nowSocket, recvBuf, BUF_SIZE); //receive a message
            recvBuf[nread] = '\0'; //manually terminate string
           
            if(strcmp(recvBuf, ACK_MSG) == 0){ //if we received an ACK, we print ACK
               printf("*** received ***\n\n"); //symbolizes reception of message
            } else if(strcmp(recvBuf, LEAVING_CHATROOM_MSG) == 0){ //if other client left
               printf("*** *** *** You're friend left the chatroom. *** *** ***\n");
               deRegister(UDPsocket, argv[1], (struct sockaddr*) &servAddr, sendBuf);
               printf("Press ENTER to exit...\n");
            } else if(strstr(recvBuf, CONN_NOTICE) != NULL){ //if it is a connection notice, don't ACK
               printf("%s%s%s\n\n", KMAG, recvBuf, KCYN);
            } else { //if normal message
               send(nowSocket, ACK_MSG, sizeof(ACK_MSG), 0); //send ack of recieved and displayed
               printf("%s%s%s\n\n", KMAG, recvBuf, KCYN);
               //weirdly, we needed to do '\n' at the end...
            }
         }
      }
      close(nowSocket); //kill TCP connection
      
      //disconnet before ending
      deRegister(UDPsocket, argv[1], (struct sockaddr*) &servAddr, sendBuf);
   }

   return EXIT_SUCCESS;
}