Example #1
0
/**
 * Try to send messages from list of messages to send
 *
 * @param handle handle to DHT
 */
static void
process_pending_messages (struct GNUNET_DHT_Handle *handle)
{
  struct PendingMessage *head;

  if (NULL == handle->client)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "process_pending_messages called, but client is NULL, reconnecting\n");
    do_disconnect (handle);
    return;
  }
  if (NULL != handle->th)
    return;
  if (NULL == (head = handle->pending_head))
    return;
  handle->th =
      GNUNET_CLIENT_notify_transmit_ready (handle->client,
                                           ntohs (head->msg->size),
                                           GNUNET_TIME_UNIT_FOREVER_REL,
                                           GNUNET_YES, &transmit_pending,
                                           handle);
  if (NULL != handle->th)
    return;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "notify_transmit_ready returned NULL, reconnecting\n");
  do_disconnect (handle);
}
int mqtt3_handle_disconnect(struct mosquitto_db *db, struct mosquitto *context)
{
	if(!context){
		return MOSQ_ERR_INVAL;
	}
	if(context->in_packet.remaining_length != 0){
		return MOSQ_ERR_PROTOCOL;
	}
	_mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received DISCONNECT from %s", context->id);
	if(context->protocol == mosq_p_mqtt311){
		if((context->in_packet.command&0x0F) != 0x00){
		    if(g_flag_epoll)
            {
                epoll_do_disconnect(db, context);
            }
            else
            {
                do_disconnect(db, context);
            }
			return MOSQ_ERR_PROTOCOL;
		}
	}
	context->state = mosq_cs_disconnecting;
    if(g_flag_epoll)
    {
        epoll_do_disconnect(db, context);
    }
    else
    {
        do_disconnect(db, context);
    }
	return MOSQ_ERR_SUCCESS;
}
Example #3
0
int GDCT_Transfer::do_send_heartbeat()
{
	ACE_ASSERT(is_connected_ == 1);
	gdct_msg_t mymsg,recvmsg;
	ACE_OS::memset(&mymsg,0,sizeof mymsg);
	ACE_OS::memset(&recvmsg,0,sizeof recvmsg);
	ACE_OS::strcpy(mymsg.msgcode,"000119");
	ACE_OS::strcpy(mymsg.msgtype,gdct_msgtype_);
	mymsg.bodylen = 0;
	
	if(do_send_and_recv(&mymsg,&recvmsg)!=0)
	{
		ACE_DEBUG((LM_ERROR,"向讯源服务器[发送心跳]失败"));
		do_disconnect();
		return -1;
	}
	if(ACE_OS::strncmp(recvmsg.msgcode,"800119",6)!=0)
	{
		ACE_DEBUG((LM_ERROR,"向讯源服务器[发送心跳]失败,接收错误数据包"));
		do_disconnect();
		return -1;
	}
	ACE_DEBUG((LM_DEBUG,"讯源服务器[发送心跳]成功!"));
	last_success_time_ = ACE_OS::gettimeofday();
	return 0;
}
Example #4
0
void MainWindow::on_actionConnect_triggered(bool checked) {
	if (m_connected) {
		do_disconnect();
	} else {
		//do_connect();
	}
}
Example #5
0
void Mount::run_disconnect(const QString &name)
{
    QString location = ctab.location(name).location;
    if (!location.length()) {
        return;
    }

    State state = mounts.state(location, name);
    if (state != connected) {
        emit (signal([&](){
              QMessageBox msgBox;
              msgBox.setWindowTitle("Fail to disconnect");
              msgBox.setText("You can disonnect not used drive only");
              msgBox.exec();
        }));
        return;
    }

	QString n;
	if (!get_canonical_name(location.toStdString(), n)) {
		if (n.startsWith("/dev/")) {
			n.remove(0, 5);
            while (n[n.size() - 1].category() != QChar::Letter_Lowercase) {
                n.resize(n.size() - 1);
            }
    		do_disconnect(n);
		}
	}
}
Example #6
0
/**
 * Disconnect from the PEERSTORE service. Any pending ITERATE and WATCH requests
 * will be canceled.
 * Any pending STORE requests will depend on @e snyc_first flag.
 *
 * @param h handle to disconnect
 * @param sync_first send any pending STORE requests before disconnecting
 */
void
GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h,
                             int sync_first)
{
  struct GNUNET_PEERSTORE_IterateContext *ic;
  struct GNUNET_PEERSTORE_StoreContext *sc;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting.\n");
  if (NULL != h->watches)
  {
    GNUNET_CONTAINER_multihashmap_iterate (h->watches, &destroy_watch, NULL);
    GNUNET_CONTAINER_multihashmap_destroy (h->watches);
    h->watches = NULL;
  }
  while (NULL != (ic = h->iterate_head))
  {
    GNUNET_break (0);
    GNUNET_PEERSTORE_iterate_cancel (ic);
  }
  if (NULL != h->store_head)
  {
    if (GNUNET_YES == sync_first)
    {
      LOG (GNUNET_ERROR_TYPE_DEBUG,
           "Delaying disconnection due to pending store requests.\n");
      h->disconnecting = GNUNET_YES;
      return;
    }
    while (NULL != (sc = h->store_head))
      GNUNET_PEERSTORE_store_cancel (sc);
  }
  do_disconnect (h);
}
Example #7
0
int
TCP_Transporter::doReceive(TransporterReceiveHandle& recvdata)
{
  // Select-function must return the socket for read
  // before this method is called
  // It reads the external TCP/IP interface once
  Uint32 size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData;
  if(size > 0){
    const int nBytesRead = (int)my_recv(theSocket,
				receiveBuffer.insertPtr,
				size < maxReceiveSize ? size : maxReceiveSize,
				0);

    if (nBytesRead > 0) {
      receiveBuffer.sizeOfData += nBytesRead;
      receiveBuffer.insertPtr  += nBytesRead;
      
      if(receiveBuffer.sizeOfData > receiveBuffer.sizeOfBuffer){
#ifdef DEBUG_TRANSPORTER
        g_eventLogger->error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
                             receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
        g_eventLogger->error("nBytesRead = %d", nBytesRead);
#endif
        g_eventLogger->error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
                             receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
	report_error(TE_INVALID_MESSAGE_LENGTH);
	return 0;
      }
      
      receiveCount ++;
      receiveSize  += nBytesRead;
      m_bytes_received += nBytesRead;
      
      if(receiveCount == reportFreq){
        recvdata.reportReceiveLen(remoteNodeId,
                                  receiveCount, receiveSize);
	receiveCount = 0;
	receiveSize  = 0;
      }
      return nBytesRead;
    } else {
#if defined DEBUG_TRANSPORTER
      g_eventLogger->error("Receive Failure(disconnect==%d) to node = %d nBytesSent = %d "
                           "errno = %d strerror = %s",
                           DISCONNECT_ERRNO(my_socket_errno(), nBytesRead),
                           remoteNodeId, nBytesRead, my_socket_errno(),
                           (char*)ndbstrerror(my_socket_errno()));
#endif   
      if(DISCONNECT_ERRNO(my_socket_errno(), nBytesRead)){
	do_disconnect(my_socket_errno());
      } 
    }
    return nBytesRead;
  } else {
    return 0;
  }
}
Example #8
0
static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pollfds)
{
	int i;

	for(i=0; i<db->context_count; i++){
		if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
			assert(pollfds[db->contexts[i]->pollfd_index].fd == db->contexts[i]->sock);
#ifdef WITH_TLS
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLOUT ||
					db->contexts[i]->want_write ||
					(db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)){
#else
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLOUT){
#endif
				if(_mosquitto_packet_write(db->contexts[i])){
					if(db->config->connection_messages == true){
						if(db->contexts[i]->state != mosq_cs_disconnecting){
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket write error on client %s, disconnecting.", db->contexts[i]->id);
						}else{
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
						}
					}
					/* Write error or other that means we should disconnect */
					mqtt3_context_disconnect(db, db->contexts[i]);
				}
			}
		}
		if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
			assert(pollfds[db->contexts[i]->pollfd_index].fd == db->contexts[i]->sock);
#ifdef WITH_TLS
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLIN ||
					db->contexts[i]->want_read ||
					(db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)){
#else
			if(pollfds[db->contexts[i]->pollfd_index].revents & POLLIN){
#endif
				if(_mosquitto_packet_read(db, db->contexts[i])){
					if(db->config->connection_messages == true){
						if(db->contexts[i]->state != mosq_cs_disconnecting){
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket read error on client %s, disconnecting.", db->contexts[i]->id);
						}else{
							_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
						}
					}
					/* Read error or other that means we should disconnect */
					mqtt3_context_disconnect(db, db->contexts[i]);
				}
			}
		}
		if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
			if(pollfds[db->contexts[i]->pollfd_index].revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)){
				do_disconnect(db, i);
			}
		}
	}
}
Example #9
0
void capturer::disconnect(){
	try{
		set_state(st_Initialization);
		do_disconnect();
	}
	catch(...){
		//TODO: journal
	}

}
Example #10
0
void ObjectData::set_type(BrowserClass * c) {
  if (type.type != c) {
    if (type.type != 0)
      do_disconnect(type.type);
    if (c != 0)
      do_connect(c);
    type.explicit_type = 0;
    type.type = c;
  }
}
Example #11
0
void ObjectData::set_type(const AType & t) {
  if (t.type != 0)
    set_type(t.type);
  else {
    if (type.type != 0) {
      do_disconnect(type.type);
      type.type = 0;
    }
    type.explicit_type = t.explicit_type;
  }
}
Example #12
0
/* Error ocurred, probably an fd has been closed. 
 * Loop through and check them all.
 */
static void loop_handle_errors(struct mosquitto_db *db, struct pollfd *pollfds)
{
	int i;

	for(i=0; i<db->context_count; i++){
		if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
			if(pollfds[db->contexts[i]->pollfd_index].revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)){
				do_disconnect(db, i);
			}
		}
	}
}
Example #13
0
/**
 * Transmit the next pending message, called by notify_transmit_ready
 *
 * @param cls the DHT handle
 * @param size number of bytes available in @a buf for transmission
 * @param buf where to copy messages for the service
 * @return number of bytes written to @a buf
 */
static size_t
transmit_pending (void *cls,
		  size_t size,
		  void *buf)
{
  struct GNUNET_DHT_Handle *handle = cls;
  struct PendingMessage *head;
  size_t tsize;


  handle->th = NULL;
  if (NULL == buf)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Transmission to DHT service failed!  Reconnecting!\n");
    do_disconnect (handle);
    return 0;
  }
  if (NULL == (head = handle->pending_head))
    return 0;

  tsize = ntohs (head->msg->size);
  if (size < tsize)
  {
    process_pending_messages (handle);
    return 0;
  }
  memcpy (buf, head->msg, tsize);
  GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail,
                               head);
  head->in_pending_queue = GNUNET_NO;
  if (NULL != head->cont)
  {
    head->cont (head->cont_cls, NULL);
    head->cont = NULL;
    head->cont_cls = NULL;
  }
  if (GNUNET_YES == head->free_on_send)
    GNUNET_free (head);
  process_pending_messages (handle);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Forwarded request of %u bytes to DHT service\n", (unsigned int) tsize);
  if (GNUNET_NO == handle->in_receive)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting to process replies from DHT\n");
    handle->in_receive = GNUNET_YES;
    
    GNUNET_CLIENT_receive (handle->client, &service_message_handler, handle,
                           GNUNET_TIME_UNIT_FOREVER_REL);
  }
  return tsize;
}
Example #14
0
/**
 * Cancel a store request
 *
 * @param sc Store request context
 */
void
GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
{
  struct GNUNET_PEERSTORE_Handle *h = sc->h;

  GNUNET_CONTAINER_DLL_remove (sc->h->store_head, sc->h->store_tail, sc);
  GNUNET_free (sc->sub_system);
  GNUNET_free (sc->value);
  GNUNET_free (sc->key);
  GNUNET_free (sc);
  if ((GNUNET_YES == h->disconnecting) && (NULL == h->store_head))
    do_disconnect (h);
}
Example #15
0
/* Error ocurred, probably an fd has been closed.
 * Loop through and check them all.
 */
static void loop_handle_errors(struct mosquitto_db *db, struct epoll_event *events, int efd)
{
    int i;
    int s;

    for(i=0; i<db->context_count; i++){
        if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
            if(events[db->contexts[i]->pollfd_index].events & (EPOLLHUP | EPOLLRDHUP | EPOLLERR)){
                s = epoll_ctl (efd, EPOLL_CTL_DEL, events[db->contexts[i]->pollfd_index].data.fd, &events[db->contexts[i]->pollfd_index]);
                do_disconnect(db, i);
            }
        }
    }
}
int mqtt3_handle_disconnect(struct mosquitto_db *db, struct mosquitto *context)
{
	if(!context){
		return MOSQ_ERR_INVAL;
	}
	if(context->in_packet.remaining_length != 0){
		return MOSQ_ERR_PROTOCOL;
	}
	_mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received DISCONNECT from %s", context->id);
	_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Received DISCONNECT from %s  (context->state=%d)", context->id,context->state);
	if(context->protocol == mosq_p_mqtt311){
		if((context->in_packet.command&0x0F) != 0x00){
               _mosquitto_log_printf(NULL,MOSQ_LOG_INFO,"read_handle_server.c:mqtt3_handle_disconnect():calling do_disconnect....6 (context->state=%d)",context->state);

			do_disconnect(db, context);
			return MOSQ_ERR_PROTOCOL;
		}
	}
	context->state = mosq_cs_disconnecting;
       _mosquitto_log_printf(NULL,MOSQ_LOG_INFO,"read_handle_server.c:mqtt3_handle_disconnect():calling do_disconnect....7 (context->state=%d)",context->state);
	do_disconnect(db, context);
	return MOSQ_ERR_SUCCESS;
}
Example #17
0
static gboolean do_connect(MegaHttpClient* http_client, GCancellable* cancellable, GError** err)
{
  GError* local_err = NULL;

  g_return_val_if_fail(MEGA_IS_HTTP_CLIENT(http_client), FALSE);
  g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

  MegaHttpClientPrivate* priv = http_client->priv;

  do_disconnect(http_client);

  // enable/disable TLS
  if (priv->https)
  {
    if (!g_tls_backend_supports_tls(g_tls_backend_get_default())) 
    {
      g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "TLS backend not found, please install glib-networking.");
      return FALSE;
    }

    g_socket_client_set_tls(priv->client, TRUE);
  }
  else
  {
    g_socket_client_set_tls(priv->client, FALSE);
  }


  priv->conn = g_socket_client_connect_to_host(priv->client, priv->host, priv->port, cancellable, &local_err);
  if (!priv->conn)
  {
    g_propagate_prefixed_error(err, local_err, "Connection failed: ");
    return FALSE;
  }
  
  GDataInputStream* data_stream = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(http_client->priv->conn)));
  g_data_input_stream_set_newline_type(data_stream, G_DATA_STREAM_NEWLINE_TYPE_ANY);

  priv->istream = G_INPUT_STREAM(data_stream);
  priv->ostream = g_object_ref(g_io_stream_get_output_stream(G_IO_STREAM(http_client->priv->conn)));

  return TRUE;
}
Example #18
0
/**
 * Transmit request from queue to datastore service.
 *
 * @param cls the 'struct GNUNET_DATASTORE_Handle'
 * @param size number of bytes that can be copied to buf
 * @param buf where to copy the drop message
 * @return number of bytes written to buf
 */
static size_t
transmit_request (void *cls, size_t size, void *buf)
{
  struct GNUNET_DATASTORE_Handle *h = cls;
  struct GNUNET_DATASTORE_QueueEntry *qe;
  size_t msize;

  h->th = NULL;
  if (NULL == (qe = h->queue_head))
    return 0;                   /* no entry in queue */
  if (buf == NULL)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to transmit request to DATASTORE.\n");
    GNUNET_STATISTICS_update (h->stats,
                              gettext_noop ("# transmission request failures"),
                              1, GNUNET_NO);
    do_disconnect (h);
    return 0;
  }
  if (size < (msize = qe->message_size))
  {
    process_queue (h);
    return 0;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u byte request to DATASTORE\n",
       msize);
  memcpy (buf, &qe[1], msize);
  qe->was_transmitted = GNUNET_YES;
  GNUNET_SCHEDULER_cancel (qe->task);
  qe->task = GNUNET_SCHEDULER_NO_TASK;
  GNUNET_assert (GNUNET_NO == h->in_receive);
  h->in_receive = GNUNET_YES;
  GNUNET_CLIENT_receive (h->client, &receive_cb, h,
                         GNUNET_TIME_absolute_get_remaining (qe->timeout));
#if INSANE_STATISTICS
  GNUNET_STATISTICS_update (h->stats,
                            gettext_noop ("# bytes sent to datastore"), 1,
                            GNUNET_NO);
#endif
  return msize;
}
Example #19
0
int GDCT_Transfer::svc()
{
	// 1 连接讯源服务器
	// 2 向讯源服务器签到
	// 3 退出时签退
	do_setup();
	is_connected_ = 0;
	// 进入主循环
	while(KsgGetGateway()->is_running())
	{
		if(is_connected_!=1)
		{
			if(do_connect_svr()!=0)
			{
				KSG_SLEEP(5000);
				continue;
			}
			if(do_login_svr()!=0)
			{
				// 登陆失败!
				do_disconnect();
				KSG_SLEEP(5000);
				continue;
			}
		}
		ACE_Time_Value now_time = ACE_OS::gettimeofday();
		if(now_time.sec()-this->last_success_time_.sec() > 180)
		{
			// 有 180s 没有通讯成功,进行一次心跳测试
			do_send_heartbeat();
			continue;
		}
		do_main_service();
	}
	return 0;
}
Example #20
0
/* Since we are operating in binary mode, the return value from control
 * is irrelevant, as long as it is not negative.
 */
static int control(ErlDrvData drv_data, unsigned int command, char *buf, 
		   int len, char **rbuf, int rlen)
{
    int r;
    char* s;

    s = get_s(buf, len);
    switch (command) {
    case DRV_CONNECT:
        r = do_connect(s, (our_data_t*)drv_data);
        break;
    case DRV_DISCONNECT:
	r = do_disconnect((our_data_t*)drv_data);
	break;
    case DRV_SELECT:
	r = do_select(s, (our_data_t*)drv_data);
	break;
    default:
	r = -1;
	break;
    }
    free_s(s);
    return r;
}
Example #21
0
/**
 * Handler for messages received from the DHT service
 * a demultiplexer which handles numerous message types
 *
 * @param cls the `struct GNUNET_DHT_Handle`
 * @param msg the incoming message
 */
static void
service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_DHT_Handle *handle = cls;
  const struct GNUNET_DHT_ClientResultMessage *dht_msg;
  uint16_t msize;
  int ret;


  if (NULL == msg)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Error receiving data from DHT service, reconnecting\n");
    do_disconnect (handle);
    return;
  }
  GNUNET_CLIENT_receive (handle->client, &service_message_handler, handle,
                         GNUNET_TIME_UNIT_FOREVER_REL);
  ret = GNUNET_SYSERR;
  msize = ntohs (msg->size);
  switch (ntohs (msg->type))
  {
  case GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET:
    if (msize < sizeof (struct GNUNET_DHT_MonitorGetMessage))
    {
      GNUNET_break (0);
      break;
    }
    ret = process_monitor_get_message(handle,
				      (const struct GNUNET_DHT_MonitorGetMessage *) msg);
    break;
  case GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP:
    if (msize < sizeof (struct GNUNET_DHT_MonitorGetRespMessage))
    {
      GNUNET_break (0);
      break;
    }
    ret = process_monitor_get_resp_message(handle,
					   (const struct GNUNET_DHT_MonitorGetRespMessage *) msg);
    break;
  case GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT:
    if (msize < sizeof (struct GNUNET_DHT_MonitorPutMessage))
    {
      GNUNET_break (0);
      break;
    }
    ret = process_monitor_put_message(handle,
				      (const struct GNUNET_DHT_MonitorPutMessage *) msg);
    break;
  case GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT_RESP:
    /* Not implemented yet */
    GNUNET_break(0);
    break;
  case GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT:
    if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_ClientResultMessage))
    {
      GNUNET_break (0);
      break;
    }
    dht_msg = (const struct GNUNET_DHT_ClientResultMessage *) msg;
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Received reply for `%s' from DHT service %p\n",
         GNUNET_h2s (&dht_msg->key), handle);
    GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests,
						&dht_msg->key,
						&process_reply,
						(void *) dht_msg);
    ret = GNUNET_OK;
    break;
  case GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK:
    if (ntohs (msg->size) != sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage))
    {
      GNUNET_break (0);
      break;
    }
    ret = process_put_confirmation_message (handle,
					    (const struct GNUNET_DHT_ClientPutConfirmationMessage*) msg);
    break;
#if ENABLE_MALICIOUS
    case GNUNET_MESSAGE_TYPE_DHT_CLIENT_ACT_MALICIOUS_OK:
       if(msize != sizeof (struct GNUNET_DHT_ClientActMaliciousConfirmationMessage))
       {
         GNUNET_break (0);
         break;
       }
       ret = process_act_malicious_confirmation_message (handle,
					    (const struct GNUNET_DHT_ClientActMaliciousConfirmationMessage*) msg);
      break;
#endif
  default:
    GNUNET_break(0);
    LOG (GNUNET_ERROR_TYPE_WARNING,
         "Unknown DHT message type: %hu (%hu) size: %hu\n",
         ntohs (msg->type), msg->type, msize);
    break;
  }
  if (GNUNET_OK != ret)
  {
    GNUNET_break (0);
    do_disconnect (handle);
    return;
  }
}
int mqtt3_handle_connect(struct mosquitto_db *db, struct mosquitto *context)
{
	char *protocol_name = NULL;
	uint8_t protocol_version;
	uint8_t connect_flags;
	uint8_t connect_ack = 0;
	char *client_id = NULL;
	char *will_payload = NULL, *will_topic = NULL;
	char *will_topic_mount;
	uint16_t will_payloadlen;
	struct mosquitto_message *will_struct = NULL;
	uint8_t will, will_retain, will_qos, clean_session;
	uint8_t username_flag, password_flag;
	char *username = NULL, *password = NULL;
	int rc;
	struct _mosquitto_acl_user *acl_tail;
	struct mosquitto_client_msg *msg_tail, *msg_prev;
	struct mosquitto *found_context;
	int slen;
	struct _mosquitto_subleaf *leaf;
	int i;
#ifdef WITH_TLS
	X509 *client_cert = NULL;
	X509_NAME *name;
	X509_NAME_ENTRY *name_entry;
#endif

#ifdef WITH_SYS_TREE
	g_connection_count++;
#endif
    g_epoll_mqtt_connections++;

	/* Don't accept multiple CONNECT commands. */
	if(context->state != mosq_cs_new){
		rc = MOSQ_ERR_PROTOCOL;
		goto handle_connect_error;
	}

	if(_mosquitto_read_string(&context->in_packet, &protocol_name)){
		rc = 1;
		goto handle_connect_error;
		return 1;
	}
	if(!protocol_name){
		rc = 3;
		goto handle_connect_error;
		return 3;
	}
	if(_mosquitto_read_byte(&context->in_packet, &protocol_version)){
		rc = 1;
		goto handle_connect_error;
		return 1;
	}
	if(!strcmp(protocol_name, PROTOCOL_NAME_v31)){
		if((protocol_version&0x7F) != PROTOCOL_VERSION_v31){
			if(db->config->connection_messages == true){
				_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.",
						protocol_version, context->address);
			}
			_mosquitto_send_connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION);
			_mosquitto_free(protocol_name);
			rc = MOSQ_ERR_PROTOCOL;
			goto handle_connect_error;
		}
		context->protocol = mosq_p_mqtt31;
	}else if(!strcmp(protocol_name, PROTOCOL_NAME_v311)){
		if((protocol_version&0x7F) != PROTOCOL_VERSION_v311){
			if(db->config->connection_messages == true){
				_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.",
						protocol_version, context->address);
			}
			_mosquitto_send_connack(context, 0, CONNACK_REFUSED_PROTOCOL_VERSION);
			_mosquitto_free(protocol_name);
			rc = MOSQ_ERR_PROTOCOL;
			goto handle_connect_error;
		}
		if((context->in_packet.command&0x0F) != 0x00){
			/* Reserved flags not set to 0, must disconnect. */ 
			_mosquitto_free(protocol_name);
			rc = MOSQ_ERR_PROTOCOL;
			goto handle_connect_error;
		}
		context->protocol = mosq_p_mqtt311;
	}else{
		if(db->config->connection_messages == true){
			_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid protocol \"%s\" in CONNECT from %s.",
					protocol_name, context->address);
		}
		_mosquitto_free(protocol_name);
		rc = MOSQ_ERR_PROTOCOL;
		goto handle_connect_error;
	}
	_mosquitto_free(protocol_name);

	if(_mosquitto_read_byte(&context->in_packet, &connect_flags)){
		rc = 1;
		goto handle_connect_error;
	}
	clean_session = (connect_flags & 0x02) >> 1;
	will = connect_flags & 0x04;
	will_qos = (connect_flags & 0x18) >> 3;
	if(will_qos == 3){
		_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid Will QoS in CONNECT from %s.",
				context->address);
		rc = MOSQ_ERR_PROTOCOL;
		goto handle_connect_error;
	}
	will_retain = connect_flags & 0x20;
	password_flag = connect_flags & 0x40;
	username_flag = connect_flags & 0x80;

	if(_mosquitto_read_uint16(&context->in_packet, &(context->keepalive))){
		rc = 1;
		goto handle_connect_error;
	}

	if(_mosquitto_read_string(&context->in_packet, &client_id)){
		rc = 1;
		goto handle_connect_error;
	}

	slen = strlen(client_id);
	if(slen == 0){
		if(context->protocol == mosq_p_mqtt31){
			_mosquitto_send_connack(context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED);
			rc = MOSQ_ERR_PROTOCOL;
			goto handle_connect_error;
		}else{ /* mqtt311 */
			_mosquitto_free(client_id);
			client_id = NULL;

			if(clean_session == 0 || db->config->allow_zero_length_clientid == false){
				_mosquitto_send_connack(context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED);
				rc = MOSQ_ERR_PROTOCOL;
				goto handle_connect_error;
			}else{
				client_id = client_id_gen(db);
				if(!client_id){
					rc = MOSQ_ERR_NOMEM;
					goto handle_connect_error;
				}
			}
		}
	}

	/* clientid_prefixes check */
	if(db->config->clientid_prefixes){
		if(strncmp(db->config->clientid_prefixes, client_id, strlen(db->config->clientid_prefixes))){
			_mosquitto_send_connack(context, 0, CONNACK_REFUSED_NOT_AUTHORIZED);
			rc = 1;
			goto handle_connect_error;
		}
	}

	if(will){
		will_struct = _mosquitto_calloc(1, sizeof(struct mosquitto_message));
		if(!will_struct){
			rc = MOSQ_ERR_NOMEM;
			goto handle_connect_error;
		}
		if(_mosquitto_read_string(&context->in_packet, &will_topic)){
			rc = 1;
			goto handle_connect_error;
		}
		if(STREMPTY(will_topic)){
			rc = 1;
			goto handle_connect_error;
		}

		if(context->listener && context->listener->mount_point){
			slen = strlen(context->listener->mount_point) + strlen(will_topic);
			will_topic_mount = _mosquitto_malloc(slen+1);
			if(!will_topic_mount){
				rc = MOSQ_ERR_NOMEM;
				goto handle_connect_error;
			}
			snprintf(will_topic_mount, slen, "%s%s", context->listener->mount_point, will_topic);
			will_topic_mount[slen] = '\0';

			_mosquitto_free(will_topic);
			will_topic = will_topic_mount;
		}

		if(mosquitto_pub_topic_check(will_topic)){
			rc = 1;
			goto handle_connect_error;
		}

		if(_mosquitto_read_uint16(&context->in_packet, &will_payloadlen)){
			rc = 1;
			goto handle_connect_error;
		}
		if(will_payloadlen > 0){
			will_payload = _mosquitto_malloc(will_payloadlen);
			if(!will_payload){
				rc = 1;
				goto handle_connect_error;
			}

			rc = _mosquitto_read_bytes(&context->in_packet, will_payload, will_payloadlen);
			if(rc){
				rc = 1;
				goto handle_connect_error;
			}
		}
	}else{
		if(context->protocol == mosq_p_mqtt311){
			if(will_qos != 0 || will_retain != 0){
				rc = MOSQ_ERR_PROTOCOL;
				goto handle_connect_error;
			}
		}
	}

	if(username_flag){
		rc = _mosquitto_read_string(&context->in_packet, &username);
		if(rc == MOSQ_ERR_SUCCESS){
			if(password_flag){
				rc = _mosquitto_read_string(&context->in_packet, &password);
				if(rc == MOSQ_ERR_NOMEM){
					rc = MOSQ_ERR_NOMEM;
					goto handle_connect_error;
				}else if(rc == MOSQ_ERR_PROTOCOL){
					if(context->protocol == mosq_p_mqtt31){
						/* Password flag given, but no password. Ignore. */
						password_flag = 0;
					}else if(context->protocol == mosq_p_mqtt311){
						rc = MOSQ_ERR_PROTOCOL;
						goto handle_connect_error;
					}
				}
			}
		}else if(rc == MOSQ_ERR_NOMEM){
			rc = MOSQ_ERR_NOMEM;
			goto handle_connect_error;
		}else{
			if(context->protocol == mosq_p_mqtt31){
				/* Username flag given, but no username. Ignore. */
				username_flag = 0;
			}else if(context->protocol == mosq_p_mqtt311){
				rc = MOSQ_ERR_PROTOCOL;
				goto handle_connect_error;
			}
		}
	}else{
		if(context->protocol == mosq_p_mqtt311){
			if(password_flag){
				/* username_flag == 0 && password_flag == 1 is forbidden */
				rc = MOSQ_ERR_PROTOCOL;
				goto handle_connect_error;
			}
		}
	}

#ifdef WITH_TLS
	if(context->listener && context->listener->ssl_ctx && context->listener->use_identity_as_username){
		if(!context->ssl){
			_mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD);
			rc = 1;
			goto handle_connect_error;
		}
#ifdef REAL_WITH_TLS_PSK
		if(context->listener->psk_hint){
			/* Client should have provided an identity to get this far. */
			if(!context->username){
				_mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD);
				rc = 1;
				goto handle_connect_error;
			}
		}else{
#endif /* REAL_WITH_TLS_PSK */
			client_cert = SSL_get_peer_certificate(context->ssl);
			if(!client_cert){
				_mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD);
				rc = 1;
				goto handle_connect_error;
			}
			name = X509_get_subject_name(client_cert);
			if(!name){
				_mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD);
				rc = 1;
				goto handle_connect_error;
			}

			i = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
			if(i == -1){
				_mosquitto_send_connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD);
				rc = 1;
				goto handle_connect_error;
			}
			name_entry = X509_NAME_get_entry(name, i);
			context->username = _mosquitto_strdup((char *)ASN1_STRING_data(name_entry->value));
			if(!context->username){
				rc = 1;
				goto handle_connect_error;
			}
			X509_free(client_cert);
			client_cert = NULL;
#ifdef REAL_WITH_TLS_PSK
		}
#endif /* REAL_WITH_TLS_PSK */
	}else{
#endif /* WITH_TLS */
		if(username_flag){
			rc = mosquitto_unpwd_check(db, username, password);
			switch(rc){
				case MOSQ_ERR_SUCCESS:
					break;
				case MOSQ_ERR_AUTH:
					_mosquitto_send_connack(context, 0, CONNACK_REFUSED_NOT_AUTHORIZED);
					mqtt3_context_disconnect(db, context);
					rc = 1;
					goto handle_connect_error;
					break;
				default:
					mqtt3_context_disconnect(db, context);
					rc = 1;
					goto handle_connect_error;
					break;
			}
			context->username = username;
			context->password = password;
			username = NULL; /* Avoid free() in error: below. */
			password = NULL;
		}

		if(!username_flag && db->config->allow_anonymous == false){
			_mosquitto_send_connack(context, 0, CONNACK_REFUSED_NOT_AUTHORIZED);
			rc = 1;
			goto handle_connect_error;
		}
#ifdef WITH_TLS
	}
#endif

	if(context->listener && context->listener->use_username_as_clientid){
		if(context->username){
			_mosquitto_free(client_id);
			client_id = _mosquitto_strdup(context->username);
			if(!client_id){
				rc = MOSQ_ERR_NOMEM;
				goto handle_connect_error;
			}
		}else{
			_mosquitto_send_connack(context, 0, CONNACK_REFUSED_NOT_AUTHORIZED);
			rc = 1;
			goto handle_connect_error;
		}
	}

	/* Find if this client already has an entry. This must be done *after* any security checks. */
	HASH_FIND(hh_id, db->contexts_by_id, client_id, strlen(client_id), found_context);
	if(found_context){
		/* Found a matching client */
		if(found_context->sock == INVALID_SOCKET){
			/* Client is reconnecting after a disconnect */
			/* FIXME - does anything need to be done here? */
		}else{
			/* Client is already connected, disconnect old version. This is
			 * done in mqtt3_context_cleanup() below. */
			if(db->config->connection_messages == true){
				_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Client %s already connected, closing old connection.", client_id);
			}
		}

		if(context->protocol == mosq_p_mqtt311){
			if(clean_session == 0){
				connect_ack |= 0x01;
			}
		}

		context->clean_session = clean_session;

		if(context->clean_session == false && found_context->clean_session == false){
			if(found_context->msgs){
				context->msgs = found_context->msgs;
				found_context->msgs = NULL;
				mqtt3_db_message_reconnect_reset(db, context);
			}
			context->subs = found_context->subs;
			found_context->subs = NULL;
			context->sub_count = found_context->sub_count;
			found_context->sub_count = 0;

			for(i=0; i<context->sub_count; i++){
				if(context->subs[i]){
					leaf = context->subs[i]->subs;
					while(leaf){
						if(leaf->context == found_context){
							leaf->context = context;
						}
						leaf = leaf->next;
					}
				}
			}
		}

		found_context->clean_session = true;
		found_context->state = mosq_cs_disconnecting;
        if(g_flag_epoll)
        {
            epoll_do_disconnect(db,found_context);
        }
        else
        {
            do_disconnect(db, found_context);
        }
		
	}

	/* Associate user with its ACL, assuming we have ACLs loaded. */
	if(db->acl_list){
		acl_tail = db->acl_list;
		while(acl_tail){
			if(context->username){
				if(acl_tail->username && !strcmp(context->username, acl_tail->username)){
					context->acl_list = acl_tail;
					break;
				}
			}else{
				if(acl_tail->username == NULL){
					context->acl_list = acl_tail;
					break;
				}
			}
			acl_tail = acl_tail->next;
		}
	}else{
		context->acl_list = NULL;
	}

	if(will_struct){
		context->will = will_struct;
		context->will->topic = will_topic;
		if(will_payload){
			context->will->payload = will_payload;
			context->will->payloadlen = will_payloadlen;
		}else{
			context->will->payload = NULL;
			context->will->payloadlen = 0;
		}
		context->will->qos = will_qos;
		context->will->retain = will_retain;
	}

	if(db->config->connection_messages == true){
		if(context->is_bridge){
			if(context->username){
				_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "New bridge connected from %s as %s (c%d, k%d, u'%s').", context->address, client_id, clean_session, context->keepalive, context->username);
			}else{
				_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "New bridge connected from %s as %s (c%d, k%d).", context->address, client_id, clean_session, context->keepalive);
			}
		}else{
			if(context->username){
				_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "New client connected from %s as %s (c%d, k%d, u'%s').", context->address, client_id, clean_session, context->keepalive, context->username);
			}else{
				_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "New client connected from %s as %s (c%d, k%d).", context->address, client_id, clean_session, context->keepalive);
			}
		}
	}

	context->id = client_id;
	client_id = NULL;
	context->clean_session = clean_session;
	context->ping_t = 0;
	context->is_dropping = false;
	if((protocol_version&0x80) == 0x80){
		context->is_bridge = true;
	}

	/* Remove any queued messages that are no longer allowed through ACL,
	 * assuming a possible change of username. */
	msg_tail = context->msgs;
	msg_prev = NULL;
	while(msg_tail){
		if(msg_tail->direction == mosq_md_out){
			if(mosquitto_acl_check(db, context, msg_tail->store->topic, MOSQ_ACL_READ) != MOSQ_ERR_SUCCESS){
				mosquitto__db_msg_store_deref(db, &msg_tail->store);
				if(msg_prev){
					msg_prev->next = msg_tail->next;
					_mosquitto_free(msg_tail);
					msg_tail = msg_prev->next;
				}else{
					context->msgs = context->msgs->next;
					_mosquitto_free(msg_tail);
					msg_tail = context->msgs;
				}
			}else{
				msg_prev = msg_tail;
				msg_tail = msg_tail->next;
			}
		}else{
			msg_prev = msg_tail;
			msg_tail = msg_tail->next;
		}
	}

	HASH_ADD_KEYPTR(hh_id, db->contexts_by_id, context->id, strlen(context->id), context);

#ifdef WITH_PERSISTENCE
	if(!clean_session){
		db->persistence_changes++;
	}
#endif
	context->state = mosq_cs_connected;
	return _mosquitto_send_connack(context, connect_ack, CONNACK_ACCEPTED);

handle_connect_error:
	if(client_id) _mosquitto_free(client_id);
	if(username) _mosquitto_free(username);
	if(password) _mosquitto_free(password);
	if(will_payload) _mosquitto_free(will_payload);
	if(will_topic) _mosquitto_free(will_topic);
	if(will_struct) _mosquitto_free(will_struct);
#ifdef WITH_TLS
	if(client_cert) X509_free(client_cert);
#endif
	/* We return an error here which means the client is freed later on. */
	return rc;
}
Example #23
0
/*
 * HTTP client state machine:
 *
 * API can request only certain state transitions, others will result in error.
 *
 *  - none -> init-connected
 *  - none-connected -> init-connected
 *  - init-connected -> headers-sent -> body-sent -> headers-received   (any combinations in the right direction)
 *  - headers-received -> (none | none-connected)
 *  - [any] -> none
 *  - [any] -> failed
 *
 *  Any other requests will fail.
 *
 *  Also depending on the number of bytes read/written some transitions may
 *  fail.
 */
static gboolean goto_state(MegaHttpClient* http_client, gint target_state, GCancellable* cancellable, GError** err)
{
  GError* local_err = NULL;

  g_return_val_if_fail(MEGA_IS_HTTP_CLIENT(http_client), FALSE);
  g_return_val_if_fail(target_state >= CONN_STATE_NONE && target_state <= CONN_STATE_FAILED, FALSE);
  g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

  MegaHttpClientPrivate* priv = http_client->priv;

  //g_print("GOTO %d -> %d\n", priv->conn_state, target_state);

  // we can always transition to NONE/FAILED states by disconnecting
  if (target_state == CONN_STATE_NONE || target_state == CONN_STATE_FAILED)
  {
    do_disconnect(http_client);
    priv->conn_state = target_state;
    return TRUE;
  }

  // perform connection
  if (target_state == CONN_STATE_INIT_CONNECTED)
  {
    if (priv->conn_state != CONN_STATE_NONE && priv->conn_state != CONN_STATE_NONE_CONNECTED && priv->conn_state != CONN_STATE_FAILED)
    {
      g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Can't connect now");
      goto err;
    }

    if (priv->conn_state == CONN_STATE_NONE || priv->conn_state == CONN_STATE_FAILED)
    {
      if (!do_connect(http_client, cancellable, &local_err))
      {
        g_propagate_error(err, local_err);
        goto err;
      }
    }

    priv->conn_state = target_state;
    return TRUE;
  }

  // we can't do nothing else in a failed state
  if (priv->conn_state == CONN_STATE_FAILED)
  {
    g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Request is in the failed state");
    goto err;
  }

  // we can get from NONE and NONE_CONNECTED only to INIT_CONNECTED by direct
  // request
  if (priv->conn_state == CONN_STATE_NONE_CONNECTED || priv->conn_state == CONN_STATE_NONE)
  {
    g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "There's no request being done!");
    goto err;
  }

  // possible start states: INIT_CONNECTED, HEADERS_SENT, BODY_SENT, HEADERS_RECEIVED
  // possible target states: HEADERS_SENT, BODY_SENT, HEADERS_RECEIVED, NONE_CONNECTED

  // check direction of the request
  if (target_state < priv->conn_state)
  {
    g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Unsupported state transition!");
    goto err;
  }

  // loop until we reach a desired state or error
  while (priv->conn_state != target_state)
  {
    // move to the next state if possible, otherwise err out
    if (priv->conn_state == CONN_STATE_INIT_CONNECTED)
    {
      if (!do_send_headers(http_client, cancellable, &local_err))
      {
        g_propagate_error(err, local_err);
        goto err;
      }

      priv->conn_state = CONN_STATE_HEADERS_SENT;
    }
    else if (priv->conn_state == CONN_STATE_HEADERS_SENT)
    {
      if (priv->expected_write_count != 0)
      {
        g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Request body is not finished");
        goto err;
      }

      priv->conn_state = CONN_STATE_BODY_SENT;
    }
    else if (priv->conn_state == CONN_STATE_BODY_SENT)
    {
      if (!do_receive_headers(http_client, cancellable, &local_err))
      {
        g_propagate_error(err, local_err);
        goto err;
      }

      priv->conn_state = CONN_STATE_HEADERS_RECEIVED;
    }
    else if (priv->conn_state == CONN_STATE_HEADERS_RECEIVED)
    {
      if (priv->expected_read_count != 0)
      {
        g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Response body is not finished");
        goto err;
      }

      priv->conn_state = CONN_STATE_NONE_CONNECTED;
    }
    else
    {
      g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Unhandled state: %d", priv->conn_state);
      goto err;
    }
  }

  return TRUE;

err:
  do_disconnect(http_client);
  priv->conn_state = CONN_STATE_FAILED;
  return FALSE;
}
Example #24
0
static void loop_handle_reads_writes(struct mosquitto_db *db, struct epoll_event *events, int efd)
{
    int i, s;

    for (i = 0; i < db->context_count; i++) {
        if (db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
            /* if (events[db->contexts[i]->pollfd_index].data.fd != db->contexts[i]->sock) { */
            /*     printf ("%d---%d\n", events[db->contexts[i]->pollfd_index].data.fd, db->contexts[i]->sock); */
            /*     printf ("%d\n", i); */
            /*     int n; */
            /*     for (n = 0; n < sizeof (db->contexts); ++n) */
            /*     { */
            /*         printf ("%d----%d\n", db->contexts[n]->pollfd_index, events[db->contexts[i]->pollfd_index].data.fd); */
            /*     } */
            /* } */
            /* assert(events[db->contexts[i]->pollfd_index].data.fd == db->contexts[i]->sock); */
#ifdef WITH_TLS
            if (events[db->contexts[i]->pollfd_index].events & EPOLLOUT ||
               db->contexts[i]->want_write ||
               (db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)) {
#else
                if(events[db->contexts[i]->epollfd_index].events & EPOLLOUT){
#endif
                    if(_mosquitto_packet_write(db->contexts[i])){
                        if(db->config->connection_messages == true){
                            if(db->contexts[i]->state != mosq_cs_disconnecting){
                                _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket write error on client %s, disconnecting.", db->contexts[i]->id);
                            }else{
                                _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
                            }
                        }
                        /* Write error or other that means we should disconnect */
                        mqtt3_context_disconnect(db, db->contexts[i]);
                    }
                }
            }
            if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
                /* assert(events[db->contexts[i]->pollfd_index].data.fd == db->contexts[i]->sock); */
#ifdef WITH_TLS
                if(events[db->contexts[i]->pollfd_index].events & EPOLLIN ||
                   db->contexts[i]->want_read ||
                   (db->contexts[i]->ssl && db->contexts[i]->state == mosq_cs_new)){
#else
                    if(events[db->contexts[i]->pollfd_index].events & EPOLLIN){
#endif
                        if(_mosquitto_packet_read(db, db->contexts[i])){
                            if(db->config->connection_messages == true){
                                if(db->contexts[i]->state != mosq_cs_disconnecting){
                                    _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Socket read error on client %s, disconnecting.", db->contexts[i]->id);
                                }else{
                                    _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client %s disconnected.", db->contexts[i]->id);
                                }
                            }
                            /* Read error or other that means we should disconnect */
                            mqtt3_context_disconnect(db, db->contexts[i]);
                        }
                    }
                }

                if(db->contexts[i] && db->contexts[i]->sock != INVALID_SOCKET){
                    if(events[db->contexts[i]->pollfd_index].events & (EPOLLHUP | POLLRDHUP | EPOLLERR)){
                        s = epoll_ctl (efd, EPOLL_CTL_DEL, events[db->contexts[i]->pollfd_index].data.fd, &events[db->contexts[i]->pollfd_index]);
                        do_disconnect(db, i);
                    }
                }
       }
}
Example #25
0
SQLRETURN api::disconnect(SQLHDBC connection_handle) const
{
	return do_disconnect(connection_handle);
}
Example #26
0
/**
 * Type of a function to call when we receive a message
 * from the service.
 *
 * @param cls closure
 * @param msg message received, NULL on timeout or fatal error
 */
static void
process_status_message (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_DATASTORE_Handle *h = cls;
  struct GNUNET_DATASTORE_QueueEntry *qe;
  struct StatusContext rc;
  const struct StatusMessage *sm;
  const char *emsg;
  int32_t status;
  int was_transmitted;

  if (NULL == (qe = h->queue_head))
  {
    GNUNET_break (0);
    do_disconnect (h);
    return;
  }
  rc = qe->qc.sc;
  if (msg == NULL)
  {
    was_transmitted = qe->was_transmitted;
    free_queue_entry (qe);
    if (was_transmitted == GNUNET_YES)
      do_disconnect (h);
    else
      process_queue (h);
    if (rc.cont != NULL)
      rc.cont (rc.cont_cls, GNUNET_SYSERR,
	       GNUNET_TIME_UNIT_ZERO_ABS,
               _("Failed to receive status response from database."));
    return;
  }
  GNUNET_assert (GNUNET_YES == qe->was_transmitted);
  free_queue_entry (qe);
  if ((ntohs (msg->size) < sizeof (struct StatusMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DATASTORE_STATUS))
  {
    GNUNET_break (0);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    do_disconnect (h);
    if (rc.cont != NULL)
      rc.cont (rc.cont_cls, GNUNET_SYSERR,
	       GNUNET_TIME_UNIT_ZERO_ABS,
               _("Error reading response from datastore service"));
    return;
  }
  sm = (const struct StatusMessage *) msg;
  status = ntohl (sm->status);
  emsg = NULL;
  if (ntohs (msg->size) > sizeof (struct StatusMessage))
  {
    emsg = (const char *) &sm[1];
    if (emsg[ntohs (msg->size) - sizeof (struct StatusMessage) - 1] != '\0')
    {
      GNUNET_break (0);
      emsg = _("Invalid error message received from datastore service");
    }
  }
  if ((status == GNUNET_SYSERR) && (emsg == NULL))
  {
    GNUNET_break (0);
    emsg = _("Invalid error message received from datastore service");
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received status %d/%s\n", (int) status, emsg);
  GNUNET_STATISTICS_update (h->stats,
                            gettext_noop ("# status messages received"), 1,
                            GNUNET_NO);
  h->retry_time = GNUNET_TIME_UNIT_ZERO;
  process_queue (h);
  if (rc.cont != NULL)
    rc.cont (rc.cont_cls, status, 
	     GNUNET_TIME_absolute_ntoh (sm->min_expiration),
	     emsg);
}
Example #27
0
/**
 * Type of a function to call when we receive a message
 * from the service.
 *
 * @param cls closure
 * @param msg message received, NULL on timeout or fatal error
 */
static void
process_result_message (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_DATASTORE_Handle *h = cls;
  struct GNUNET_DATASTORE_QueueEntry *qe;
  struct ResultContext rc;
  const struct DataMessage *dm;
  int was_transmitted;

  if (NULL == msg)
  {
    qe = h->queue_head;
    GNUNET_assert (NULL != qe);
    rc = qe->qc.rc;
    was_transmitted = qe->was_transmitted;
    free_queue_entry (qe);
    if (GNUNET_YES == was_transmitted)
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
           _("Failed to receive response from database.\n"));
      do_disconnect (h);
    }
    else
    {
      process_queue (h);
    }
    if (NULL != rc.proc)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
  if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END)
  {
    GNUNET_break (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader));
    qe = h->queue_head;
    rc = qe->qc.rc;
    GNUNET_assert (GNUNET_YES == qe->was_transmitted);
    free_queue_entry (qe);
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Received end of result set, new queue size is %u\n", h->queue_size);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    h->result_count = 0;
    process_queue (h);
    if (rc.proc != NULL)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
  qe = h->queue_head;
  GNUNET_assert (NULL != qe);
  rc = qe->qc.rc;
  if (GNUNET_YES != qe->was_transmitted)
  {
    GNUNET_break (0);
    free_queue_entry (qe);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    do_disconnect (h);
    if (rc.proc != NULL)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
  if ((ntohs (msg->size) < sizeof (struct DataMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DATASTORE_DATA) ||
      (ntohs (msg->size) !=
       sizeof (struct DataMessage) +
       ntohl (((const struct DataMessage *) msg)->size)))
  {
    GNUNET_break (0);
    free_queue_entry (qe);
    h->retry_time = GNUNET_TIME_UNIT_ZERO;
    do_disconnect (h);
    if (rc.proc != NULL)
      rc.proc (rc.proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS,
               0);
    return;
  }
#if INSANE_STATISTICS
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# Results received"), 1,
                            GNUNET_NO);
#endif
  dm = (const struct DataMessage *) msg;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Received result %llu with type %u and size %u with key %s\n",
       (unsigned long long) GNUNET_ntohll (dm->uid), ntohl (dm->type),
       ntohl (dm->size), GNUNET_h2s (&dm->key));
  free_queue_entry (qe);
  h->retry_time = GNUNET_TIME_UNIT_ZERO;
  process_queue (h);
  if (rc.proc != NULL)
    rc.proc (rc.proc_cls, &dm->key, ntohl (dm->size), &dm[1], ntohl (dm->type),
             ntohl (dm->priority), ntohl (dm->anonymity),
             GNUNET_TIME_absolute_ntoh (dm->expiration),
             GNUNET_ntohll (dm->uid));
}
Example #28
0
static void
nc_master(struct test_params *p)
{
    int s, i;
    struct sockaddr_in slave, my_addr;
    struct hostent *host;
    struct pause pause_times[] = {
        {0,0}, {1,10}, {5,10}, {10,10}, {1,1} };

    if (p->argc != 2) {
        test_printf("Need exactly 'master <host>'\n");
        return;
    }

    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) {
        pexit("datagram socket");
    }

    memset(&my_addr, 0, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
#ifdef __ECOS
    my_addr.sin_len = sizeof(my_addr);
#endif
    my_addr.sin_port = htons(NC_MASTER_PORT);
    my_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(s, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
        pexit("bind");
    }

    host = gethostbyname(p->argv[1]);
    if (host == (struct hostent *)NULL) {
        pexit("gethostbyname");
    }

    memset(&slave, 0, sizeof(slave));
    slave.sin_family = AF_INET;
#ifdef __ECOS
    slave.sin_len = sizeof(slave);
#endif
    slave.sin_port = htons(NC_SLAVE_PORT);
    memcpy(&slave.sin_addr.s_addr, host->h_addr, host->h_length);

    test_printf("================== No load, master at 100%% ========================\n");
#if 0
    do_udp_test(s, NC_REQUEST_UDP_ECHO, &slave, 640, 1024, 0, 0);
    do_udp_test(s, NC_REQUEST_UDP_SEND, &slave, 640, 1024, 0, 0);
    do_udp_test(s, NC_REQUEST_UDP_RECV, &slave, 640, 1024, 0, 0);
    do_tcp_test(s, NC_REQUEST_TCP_ECHO, &slave, 640, 1024, 0, 0);
    do_tcp_test(s, NC_REQUEST_TCP_SEND, &slave, 640, 1024, 0, 0);
    do_tcp_test(s, NC_REQUEST_TCP_RECV, &slave, 640, 1024, 0, 0);
#endif
    do_tcp_test(s, NC_REQUEST_TCP_ECHO, &slave, 64, 10240, 0, 0);

    if (do_set_load(s, &slave, 0)) {
        test_printf("\n====================== Various slave compute loads ===================\n");
        for (i = 0;  i < 60;  i += 10) {
            test_printf(">>>>>>>>>>>> slave processing load at %d%%\n", i);
            do_set_load(s, &slave, i);
            do_udp_test(s, NC_REQUEST_UDP_ECHO, &slave, 2048, 1024, 0, 0);
            do_tcp_test(s, NC_REQUEST_TCP_ECHO, &slave, 2048, 1024, 0, 0);
        }
    }

    if (do_start_idle(s, &slave)) {
        test_printf("\n====================== Various master loads ===================\n");
        test_printf("Testing IDLE for %d seconds\n", IDLE_TEST_TIME);
        test_delay(IDLE_TEST_TIME*100);
        do_stop_idle(s, &slave, true);
        for (i = 0;  i < LENGTH(pause_times);  i++) {
            do_start_idle(s, &slave);
            do_udp_test(s, NC_REQUEST_UDP_ECHO, &slave, 2048, 1024, 
                        pause_times[i].pause_ticks, pause_times[i].pause_threshold);
            do_stop_idle(s, &slave, false);
            do_start_idle(s, &slave);
            do_tcp_test(s, NC_REQUEST_TCP_ECHO, &slave, 2048, 1024, 
                        pause_times[i].pause_ticks, pause_times[i].pause_threshold);
            do_stop_idle(s, &slave, false);
        }
    }

    do_disconnect(s, &slave);
    close(s);
}
Example #29
0
static void stop(ErlDrvData drv_data)
{
    do_disconnect((our_data_t*)drv_data);
}
Example #30
0
static int callback_mqtt(struct libwebsocket_context *context,
#endif
		struct libwebsocket *wsi,
		enum libwebsocket_callback_reasons reason,
		void *user,
		void *in,
		size_t len)
{
	struct mosquitto_db *db;
	struct mosquitto *mosq = NULL;
	struct mosquitto__packet *packet;
	int count, i, j;
	const struct libwebsocket_protocols *p;
	struct libws_mqtt_data *u = (struct libws_mqtt_data *)user;
	size_t pos;
	uint8_t *buf;
	int rc;
	uint8_t byte;

	db = &int_db;

	switch (reason) {
		case LWS_CALLBACK_ESTABLISHED:
			mosq = context__init(db, WEBSOCKET_CLIENT);
			if(mosq){
				p = libwebsockets_get_protocol(wsi);
				for (i=0; i<db->config->listener_count; i++){
					if (db->config->listeners[i].protocol == mp_websockets) {
						for (j=0; db->config->listeners[i].ws_protocol[j].name; j++){
							if (p == &db->config->listeners[i].ws_protocol[j]){
								mosq->listener = &db->config->listeners[i];
								mosq->listener->client_count++;
							}
						}
					}
				}
				if(!mosq->listener){
					mosquitto__free(mosq);
					return -1;
				}
#if !defined(LWS_LIBRARY_VERSION_NUMBER)
				mosq->ws_context = context;
#endif
				mosq->wsi = wsi;
#ifdef WITH_TLS
				if(in){
					mosq->ssl = (SSL *)in;
					if(!mosq->listener->ssl_ctx){
						mosq->listener->ssl_ctx = SSL_get_SSL_CTX(mosq->ssl);
					}
				}
#endif
				u->mosq = mosq;
			}else{
				return -1;
			}
			easy_address(libwebsocket_get_socket_fd(wsi), mosq);
			if(!mosq->address){
				/* getpeername and inet_ntop failed and not a bridge */
				mosquitto__free(mosq);
				u->mosq = NULL;
				return -1;
			}
			if(mosq->listener->max_connections > 0 && mosq->listener->client_count > mosq->listener->max_connections){
				if(db->config->connection_messages == true){
					log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", mosq->address);
				}
				mosquitto__free(mosq);
				u->mosq = NULL;
				return -1;
			}
			mosq->sock = libwebsocket_get_socket_fd(wsi);
			HASH_ADD(hh_sock, db->contexts_by_sock, sock, sizeof(mosq->sock), mosq);
			break;

		case LWS_CALLBACK_CLOSED:
			if(!u){
				return -1;
			}
			mosq = u->mosq;
			if(mosq){
				if(mosq->sock != INVALID_SOCKET){
					HASH_DELETE(hh_sock, db->contexts_by_sock, mosq);
					mosq->sock = INVALID_SOCKET;
					mosq->pollfd_index = -1;
				}
				mosq->wsi = NULL;
#ifdef WITH_TLS
				mosq->ssl = NULL;
#endif
				do_disconnect(db, mosq);
			}
			break;

		case LWS_CALLBACK_SERVER_WRITEABLE:
			if(!u){
				return -1;
			}
			mosq = u->mosq;
			if(!mosq){
				return -1;
			}

			db__message_write(db, mosq);

			if(mosq->out_packet && !mosq->current_out_packet){
				mosq->current_out_packet = mosq->out_packet;
				mosq->out_packet = mosq->out_packet->next;
				if(!mosq->out_packet){
					mosq->out_packet_last = NULL;
				}
			}

			if(mosq->current_out_packet && !lws_send_pipe_choked(mosq->wsi)){
				packet = mosq->current_out_packet;

				if(packet->pos == 0 && packet->to_process == packet->packet_length){
					/* First time this packet has been dealt with.
					 * libwebsockets requires that the payload has
					 * LWS_SEND_BUFFER_PRE_PADDING space available before the
					 * actual data and LWS_SEND_BUFFER_POST_PADDING afterwards.
					 * We've already made the payload big enough to allow this,
					 * but need to move it into position here. */
					memmove(&packet->payload[LWS_SEND_BUFFER_PRE_PADDING], packet->payload, packet->packet_length);
					packet->pos += LWS_SEND_BUFFER_PRE_PADDING;
				}
				count = libwebsocket_write(wsi, &packet->payload[packet->pos], packet->to_process, LWS_WRITE_BINARY);
				if(count < 0){
					if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){
						return -1;
					}
					return 0;
				}
#ifdef WITH_SYS_TREE
				g_bytes_sent += count;
#endif
				packet->to_process -= count;
				packet->pos += count;
				if(packet->to_process > 0){
					if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){
						return -1;
					}
					break;
				}

#ifdef WITH_SYS_TREE
				g_msgs_sent++;
				if(((packet->command)&0xF6) == PUBLISH){
					g_pub_msgs_sent++;
				}
#endif

				/* Free data and reset values */
				mosq->current_out_packet = mosq->out_packet;
				if(mosq->out_packet){
					mosq->out_packet = mosq->out_packet->next;
					if(!mosq->out_packet){
						mosq->out_packet_last = NULL;
					}
				}

				packet__cleanup(packet);
				mosquitto__free(packet);

				mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
			}
			if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){
				return -1;
			}
			if(mosq->current_out_packet){
				libwebsocket_callback_on_writable(mosq->ws_context, mosq->wsi);
			}
			break;

		case LWS_CALLBACK_RECEIVE:
			if(!u || !u->mosq){
				return -1;
			}
			mosq = u->mosq;
			pos = 0;
			buf = (uint8_t *)in;
			G_BYTES_RECEIVED_INC(len);
			while(pos < len){
				if(!mosq->in_packet.command){
					mosq->in_packet.command = buf[pos];
					pos++;
					/* Clients must send CONNECT as their first command. */
					if(mosq->state == mosq_cs_new && (mosq->in_packet.command&0xF0) != CONNECT){
						return -1;
					}
				}
				if(mosq->in_packet.remaining_count <= 0){
					do{
						if(pos == len){
							return 0;
						}
						byte = buf[pos];
						pos++;

						mosq->in_packet.remaining_count--;
						/* Max 4 bytes length for remaining length as defined by protocol.
						* Anything more likely means a broken/malicious client.
						*/
						if(mosq->in_packet.remaining_count < -4){
							return -1;
						}

						mosq->in_packet.remaining_length += (byte & 127) * mosq->in_packet.remaining_mult;
						mosq->in_packet.remaining_mult *= 128;
					}while((byte & 128) != 0);
					mosq->in_packet.remaining_count *= -1;

					if(mosq->in_packet.remaining_length > 0){
						mosq->in_packet.payload = mosquitto__malloc(mosq->in_packet.remaining_length*sizeof(uint8_t));
						if(!mosq->in_packet.payload){
							return -1;
						}
						mosq->in_packet.to_process = mosq->in_packet.remaining_length;
					}
				}
				if(mosq->in_packet.to_process>0){
					if(len - pos >= mosq->in_packet.to_process){
						memcpy(&mosq->in_packet.payload[mosq->in_packet.pos], &buf[pos], mosq->in_packet.to_process);
						mosq->in_packet.pos += mosq->in_packet.to_process;
						pos += mosq->in_packet.to_process;
						mosq->in_packet.to_process = 0;
					}else{
						memcpy(&mosq->in_packet.payload[mosq->in_packet.pos], &buf[pos], len-pos);
						mosq->in_packet.pos += len-pos;
						mosq->in_packet.to_process -= len-pos;
						return 0;
					}
				}
				/* All data for this packet is read. */
				mosq->in_packet.pos = 0;

#ifdef WITH_SYS_TREE
				G_MSGS_RECEIVED_INC(1);
				if(((mosq->in_packet.command)&0xF5) == PUBLISH){
					G_PUB_MSGS_RECEIVED_INC(1);
				}
#endif
				rc = handle__packet(db, mosq);

				/* Free data and reset values */
				packet__cleanup(&mosq->in_packet);

				mosq->last_msg_in = mosquitto_time();

				if(rc && (mosq->out_packet || mosq->current_out_packet)) {
					if(mosq->state != mosq_cs_disconnecting){
						mosq->state = mosq_cs_disconnect_ws;
					}
					libwebsocket_callback_on_writable(mosq->ws_context, mosq->wsi);
				} else if (rc) {
					do_disconnect(db, mosq);
					return -1;
				}
			}
			break;

		default:
			break;
	}

	return 0;
}