예제 #1
0
파일: wshtp_server.c 프로젝트: rfloresx/web
static void ws_event_cb(evbev_t *bev, short what, void *args) {
    wshtp_conn_t *conn = args;

    bufferevent_lock(bev);
    if (what & BEV_EVENT_EOF || what & BEV_EVENT_ERROR || what & BEV_EVENT_TIMEOUT) {
        conn->method = WSHTP_ON_CLOSE;

        bufferevent_unlock(bev);

        wshtp_hooks_call(conn->server, conn->method, conn);

        bufferevent_lock(bev);
    }
    bufferevent_unlock(bev);
}
예제 #2
0
int MTCLink::SendPacket(SBCPacket *packet)
{
  packet->numBytes = packet->header.numberBytesinPayload + sizeof(uint32_t) +
    sizeof(SBCHeader) + kSBC_MaxMessageSizeBytes;
  int numBytesToSend = packet->numBytes;
  bufferevent_lock(fBev);
  bufferevent_write(fBev,packet,numBytesToSend);
  bufferevent_unlock(fBev);
  return 0;
}
예제 #3
0
파일: monitor.c 프로젝트: gonzopancho/zerod
/**
 * Event handler for monitor connection.
 * @param[in] bev
 * @param[in] events
 * @param[in] ctx
 */
static void zmonitor_event_cb(struct bufferevent *bev, short events, void *ctx)
{
    struct zmonitor_conn *conn = (struct zmonitor_conn *) ctx;

    if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
        bufferevent_unlock(bev);
        zmonitor_conn_deactivate(conn);
        bufferevent_lock(bev);
        zmonitor_conn_free(conn);
    }
}
예제 #4
0
int MTCLink::SendXilinxPacket(SBCPacket *packet, int waitSeconds)
{
  int numBytesToSend = packet->numBytes;
  bufferevent_lock(fBev);
  bufferevent_write(fBev,packet,numBytesToSend);
  bufferevent_unlock(fBev);
  int bytesRecved = 0;
  while (true){
    pthread_mutex_lock(&fRecvQueueLock);
    if (waitSeconds){
      struct timeval tp;
      struct timespec ts;
      gettimeofday(&tp, NULL);
      ts.tv_sec  = tp.tv_sec;
      ts.tv_nsec = tp.tv_usec * 1000;
      ts.tv_sec += waitSeconds;
      while (fRecvQueue.empty()){
        int rc = pthread_cond_timedwait(&fRecvQueueCond,&fRecvQueueLock,&ts);
        if (rc == ETIMEDOUT) {
          lprintf("MTCLink::SendXilinxPacket: Wait timed out!\n");
          rc = pthread_mutex_unlock(&fRecvQueueLock);
          return 1;
        }
      }
    }else{
      while (fRecvQueue.empty())
        pthread_cond_wait(&fRecvQueueCond,&fRecvQueueLock);
    }

    *packet = fRecvQueue.front();
    fRecvQueue.pop();
    bytesRecved += packet->numBytes;
    pthread_mutex_unlock(&fRecvQueueLock);
    if (bytesRecved >= numBytesToSend)
      break;
  }
  return 0;
}
예제 #5
0
void TierClientConnectionWriteCB(TierClientConnectionRef me){
	if(me->doQuitGracefully)
		return;
	if(me->clearToSend == YES)
	{
		OCSerializerRef s = OCSerializerCreate();
		
		ALChunkRef chunk = NULL;
		while( (chunk=(ALChunkRef)OCListFifoPop(me->toSendChunks)) != NULL)
		{
			OCSerializerReset(s);
		
			ALChunkSerialize(chunk, s);
			size_t nBytes = OCSerializerGetNumberOfBytes(s);
			if(nBytes < TIER_MESSAGE_MAX_LENGTH)
			{
				struct TierMessage msg;
				msg.header.messageType = TMCHUNK;
				msg.header.protocolVariant = 0;
				msg.header.protocolVersion = 0;
				msg.header.dataLength = OCSerializerGetNumberOfBytes(s);
				OCSerializerCopyBytes(s, msg.data);
				bufferevent_lock(me->be);
				TierMessageWriteToEVBuffer(&msg, me->be->output);
				bufferevent_write_buffer(me->be, bufferevent_get_output(me->be));		
				bufferevent_unlock(me->be);
				
				OCListFifoPush(me->unackedChunks, (OCObjectRef)chunk);
			}
			// OCListFifoPop does not release the chunk, we have to do this:
			OCObjectRelease(&chunk);
		}
		OCObjectRelease(&s);		
		me->clearToSend = NO;
	}
	me->clearToSend = YES;
}
예제 #6
0
void MTCLink::RecvCallback(struct bufferevent *bev)
{
  int totalLength = 0;
  int n;
  char input[10000];
  memset(input,'\0',10000);
  while (1){
    bufferevent_lock(bev);
    n = bufferevent_read(bev, input+strlen(input), sizeof(input));
    bufferevent_unlock(bev);
    totalLength += n;
    if (n <= 0)
      break;
  }

  char *inputP = input;
  while (totalLength > 0){
    if (fTempBytes == 0){
      int numThisPacket = ((SBCPacket *) inputP)->numBytes;
      if (numThisPacket > totalLength){
        memcpy(fTempPacket,inputP,totalLength);
        fBytesLeft = numThisPacket-totalLength; 
        fTempBytes = totalLength;
        break;
      }else{
        memcpy(fTempPacket,inputP,numThisPacket);
        SBCPacket *packet = (SBCPacket *) fTempPacket;
        pthread_mutex_lock(&fRecvQueueLock);
        fRecvQueue.push(*packet);
        //lprintf("Got packet, size %d empty %d\n",fRecvQueue.size(),fRecvQueue.empty());
        pthread_cond_signal(&fRecvQueueCond);
        pthread_mutex_unlock(&fRecvQueueLock);
        memset(fTempPacket,0,sizeof(fTempPacket));
        totalLength -= numThisPacket;
        inputP += numThisPacket;
      }
    }else{
      if (fBytesLeft > totalLength){
        memcpy(fTempPacket+fTempBytes,inputP,totalLength);
        fBytesLeft -= totalLength; 
        fTempBytes += totalLength;
        break;
      }else{
        memcpy(fTempPacket+fTempBytes,inputP,fBytesLeft);
        SBCPacket *packet = (SBCPacket *) fTempPacket;
        pthread_mutex_lock(&fRecvQueueLock);
        fRecvQueue.push(*packet);
        //lprintf("Got packet, size %d empty %d\n",fRecvQueue.size(),fRecvQueue.empty());
        pthread_cond_signal(&fRecvQueueCond);
        pthread_mutex_unlock(&fRecvQueueLock);
        memset(fTempPacket,0,sizeof(fTempPacket));
        inputP += fBytesLeft;
        totalLength -= fBytesLeft;
        fBytesLeft = 0;
        fTempBytes = 0;
      }
    }
  }
//  if (fTempBytes)
//    lprintf("%d bytes left\n",fBytesLeft);
}
예제 #7
0
파일: wshtp_server.c 프로젝트: rfloresx/web
static int ws_send_frame(wshtp_conn_t *conn, bool fin, uint8_t opcode,
                         const void *data, size_t size,
                         bool mask, uint32_t mask_key) {
    uint8_t byte0 = opcode;
    if (fin) {
        byte0 |= FIN;
    }
    uint8_t byte1 = 0; // maks_flag(1 bit) + payload_len(7 bits)

    size_t frame_size = 2;

    union {
        uint16_t len_16;
        uint64_t len_64;
        char bytes[8];
    } ext_payload_len;

    if (size > INT16_MAX) {
        byte1 = 127;
        frame_size += 8;
        ext_payload_len.len_64 = (uint64_t)size;
    }else if (size > 125) {
        byte1 = 126;
        frame_size += 2;
        ext_payload_len.len_16 = (uint16_t)size;
    }else {
        byte1 = (uint8_t)size;
    }
    if (mask) {
        frame_size += 4;
        byte1 |= MASK; //set mask
    }
    frame_size += size;
    char *frame_data = (char *)calloc(frame_size, sizeof(char)); //allocate frame data

    int index = 0;
    frame_data[index++] = byte0;
    frame_data[index++] = byte1;

    //SET extended payload_len if required
    if (size > INT16_MAX) {
        frame_data[index++] = ext_payload_len.bytes[7];
        frame_data[index++] = ext_payload_len.bytes[6];
        frame_data[index++] = ext_payload_len.bytes[5];
        frame_data[index++] = ext_payload_len.bytes[4];
        frame_data[index++] = ext_payload_len.bytes[3];
        frame_data[index++] = ext_payload_len.bytes[2];
        frame_data[index++] = ext_payload_len.bytes[1];
        frame_data[index++] = ext_payload_len.bytes[0];
    } else if (size > 125) {
        frame_data[index++] = ext_payload_len.bytes[1];
        frame_data[index++] = ext_payload_len.bytes[0];
    }

    //SET mask_key if MASK is set
    if (mask) {
        int32_t *i32 = (int32_t*)&frame_data[index];
        *i32 = mask_key;
        index += 4;
    }
    memcpy(&frame_data[index], data, size);

    evbev_t *bev =evhtp_connection_get_bev(conn->conn);
    evbuf_t *reply_buf = conn->conn->scratch_buf;

    evbuffer_drain(reply_buf, -1);
    evbuffer_add(reply_buf, &frame_data[0], frame_size);
    bufferevent_lock(bev);
    {
        bufferevent_write_buffer(bev, reply_buf);
    }
    bufferevent_unlock(bev);
    evbuffer_drain(reply_buf, -1);
    free(frame_data);
    return 0;
}
예제 #8
0
파일: wshtp_server.c 프로젝트: rfloresx/web
static void ws_read_cb(evbev_t * bev, void *arg) {
    size_t data_len = 0;

    wshtp_conn_t *conn = (wshtp_conn_t*)arg;

    evbuf_t *in = bufferevent_get_input(bev);

    bufferevent_lock(bev);

    while ( (data_len = evbuffer_get_length(in)) ){
        void *data = evbuffer_pullup(in, data_len);

        ws_frame_t frame;

        size_t nread = ws_parse_frame(data, data_len, &frame);

        if (frame.status == STATUS_OK) {

            if (frame.opcode == OP_TEXT) {
                conn->data.type = WS_DATA_TEXT;
                conn->method = WSHTP_ON_MESSAGE;
            } else if (frame.opcode == OP_BIN) {
                conn->data.type = WS_DATA_BINARY;
                conn->method = WSHTP_ON_MESSAGE;
            } else if (frame.opcode == OP_CLOSE) {
                conn->method = WSHTP_ON_CLOSE;
            }

            if (frame.fin == 0 || frame.opcode == OP_CONT) {
                if (conn->data.ws_frames == NULL) {
                    conn->data.ws_frames = ws_buffer_new();
                }
                ws_buffer_append_data(conn->data.ws_frames, frame.data, frame.payload_len);
            }

            if (conn->method == WSHTP_ON_CLOSE) {
                evbuffer_drain(in, data_len);
            } else {
                evbuffer_drain(in, nread);
            }

            if (frame.fin) {
                if (conn->data.ws_frames) {
                    conn->data.content = ws_buffer_get_data(conn->data.ws_frames, &conn->data.size);
                    ws_buffer_free(conn->data.ws_frames);
                    conn->data.ws_frames = NULL;
                } else {
                    conn->data.content = frame.data;
                    conn->data.size = frame.payload_len;
                }

                bufferevent_unlock(bev);

                wshtp_hooks_call(conn->server, conn->method, conn);

                bufferevent_lock(bev);

                free(conn->data.content);
                conn->data.content = NULL;
                conn->data.size = 0;
            }
        } else {
            break;
        }
    }

    // free fragments
    bufferevent_unlock(bev);
}
예제 #9
0
void MessageManager::MessageDispatcher(struct bufferevent *bev, void *ctx)
{

	bufferevent_lock(bev);

	struct evbuffer *input = bufferevent_get_input(bev);
	evutil_socket_t socketFD = bufferevent_getfd(bev);

	uint32_t length = 0, evbufferLength;

	bool keepGoing = true;
	while(keepGoing)
	{
		evbufferLength = evbuffer_get_length(input);
		//If we don't even have enough data to read the length, just quit
		if(evbufferLength < sizeof(length))
		{
			keepGoing = false;
			continue;
		}

		//Copy the length field out of the message
		//	We only want to copy this data at first, because if the whole message hasn't reached us,
		//	we'll want the whole buffer still present here, undrained
		if(evbuffer_copyout(input, &length, sizeof(length)) != sizeof(length))
		{
			keepGoing = false;
			continue;
		}

		// Make sure the length appears valid
		// TODO: Assign some arbitrary max message size to avoid filling up memory by accident
		if(length < MESSAGE_MIN_SIZE)
		{
			LOG(WARNING, "Error parsing message: message too small.", "");
			evbuffer_drain(input, sizeof(length));
			keepGoing = false;
			continue;
		}

		//If we don't yet have enough data, then just quit and wait for more
		if(evbufferLength < length)
		{
			keepGoing = false;
			continue;
		}

		evbuffer_drain(input, sizeof(length));

		//Remove the length of the "length" variable itself
		length -= sizeof(length);
		char *buffer = (char*)malloc(length);

		if(buffer == NULL)
		{
			// This should never happen. If it does, probably because length is an absurd value (or we're out of memory)
			LOG(WARNING, "Error parsing message: malloc returned NULL. Out of memory?.", "");
			free(buffer);
			keepGoing = false;
			continue;
		}

		// Read in the actual message
		int bytesRead = evbuffer_remove(input, buffer, length);
		if(bytesRead == -1)
		{
			LOG(WARNING, "Error parsing message: couldn't remove data from buffer.", "");
		}
		else if((uint32_t)bytesRead != length)
		{
			LOG(WARNING, "Error parsing message: incorrect amount of data received than what expected.", "");
		}

		MessageEndpointLock endpoint = MessageManager::Instance().GetEndpoint(socketFD);
		if(endpoint.m_endpoint != NULL)
		{
			Message *message = Message::Deserialize(buffer, length);
			if(!endpoint.m_endpoint->PushMessage(message))
			{
				LOG(DEBUG, "Discarding message. Error in pushing it to a queue.", "");
			}
		}
		else
		{
			LOG(DEBUG, "Discarding message. Received it for a non-existent endpoint.", "");
		}

		free(buffer);
	}

	bufferevent_unlock(bev);
}