示例#1
0
/*
 * dead_link - Adds client to a list of clients that need an exit_client()
 *
 */
void dead_link(struct Client *client_p)
{
  dlink_node *m;
  const char *notice;
  if(IsClosing(client_p))
    return;

  linebuf_donebuf(&client_p->localClient->buf_recvq);
  linebuf_donebuf(&client_p->localClient->buf_sendq);
  
  if(client_p->flags & FLAGS_SENDQEX)
    notice = "Max SendQ exceeded";
  else
    notice = "Dead link";
    	
  if (!IsPerson(client_p) && !IsUnknown(client_p) && !IsClosing(client_p))
  {
    sendto_realops_flags(FLAGS_ALL, L_ADMIN,
                         notice, get_client_name(client_p, HIDE_IP));
    sendto_realops_flags(FLAGS_ALL, L_OPER,
                         notice, get_client_name(client_p, MASK_IP));
  }
  Debug((DEBUG_ERROR, notice, get_client_name(to, HIDE_IP)));
  assert(dlinkFind(&abort_list, client_p) == NULL);
  m = make_dlink_node();
  dlinkAdd(client_p, m, &abort_list);
  SetDead(client_p); /* You are dead my friend */
}
示例#2
0
bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
    qDebug() << __FUNCTION__;
    REQUIRE_UI_THREAD();
    base::AutoLock lock_scope(lock_DoClose);
    // Closing the main window requires special handling. See the DoClose()
    // documentation in the CEF header for a detailed destription of this
    // process.
    /// TODO probably too late already, onbeforeunload has probably already been called.
    qDebug() << "browser->GetIdentifier():" << browser->GetIdentifier();
    if (m_BrowserId == browser->GetIdentifier() && !m_bIsClosing) {
        /// Notify the browser that the parent window is about to close.
        /// NOTE: ParentWindowWillClose appears to have been removed because it was never
        /// actually implemented.
        /// browser->ParentWindowWillClose();
        // Set a flag to indicate that the window close should be allowed.
        m_bIsClosing = true;
        qDebug() << "CEF closing step 6 a: is closing: " << IsClosing();
#ifdef WIN32
        // Maybe to CsoundQt?
        //::DestroyWindow(browser->GetHost()->GetWindowHandle());
#endif
    }
    // Allow the close. For windowed browsers this will result in the OS close
    // event being sent.
    qDebug() << "CEF closing step 6 b: is closing: " << IsClosing();
    return true;
}
示例#3
0
/* If the client never finished authenticating but is
 * registering anyway, abort the exchange.
 */
static void
abort_sasl(struct Client *data)
{
	if(data->localClient->sasl_out == 0 || data->localClient->sasl_complete)
		return;

	data->localClient->sasl_out = data->localClient->sasl_complete = 0;
	ServerStats.is_sbad++;

	if(!IsClosing(data))
		sendto_one(data, form_str(ERR_SASLABORTED), me.name, EmptyString(data->name) ? "*" : data->name);

	if(*data->localClient->sasl_agent)
	{
		struct Client *agent_p = find_id(data->localClient->sasl_agent);
		if(agent_p)
		{
			sendto_one(agent_p, ":%s ENCAP %s SASL %s %s D A", me.id, agent_p->servptr->name,
					data->id, agent_p->id);
			return;
		}
	}

	sendto_server(NULL, NULL, CAP_TS6|CAP_ENCAP, NOCAPS, ":%s ENCAP * SASL %s * D A", me.id,
			data->id);
}
示例#4
0
void Tapplication::OnIdle()
{
	if (IsClosing())
		return;
	// Dispatch idle messages to all pages
	for ( int i = 0; i < pageCount; ++i )
		pageStack[i]->OnIdle();

	if (m_pTaskManager)
		m_pTaskManager->OnIdleEvent();
}
示例#5
0
    int Udp::RecvStop()
    {
        assert(IsOpened() || IsClosing());
        assert(IsRecvStarted());

        int result = uv_udp_recv_stop(*this);

        m_pRecvHandler = NULL;
        Unref();

        return result;
    }
示例#6
0
	void TcpServer::UserOnTcpConnectionClosed(::TcpConnection* connection, bool isClosedByPeer)
	{
		MS_TRACE();

		// Notify the listener.
		// NOTE: Don't do it if closing (since at this point the listener is already freed).
		// At the end, this is just called if the connection was remotely closed.
		if (!IsClosing())
		{
			this->listener->OnRtcTcpConnectionClosed(
			  this, dynamic_cast<RTC::TcpConnection*>(connection), isClosedByPeer);
		}
	}
示例#7
0
dword Tapplication::EventHandler( word event, dword param1, dword param2 )
{
	if (IsClosing())
		return param1;

    switch ( event )
	{
	case EVT_IDLE:
		OnIdle();
		return 0;
	case EVT_KEY:
		if (m_reshowUIKey != 0)
			return OnKeyWhenHidden(param1, param2);
		return OnKey( param1, param2 );
	default:
		return OnOtherEvent(event, param1, param2);
	}

}
示例#8
0
void _free_client(struct Client* client_p)
{
  assert(NULL != client_p);
  assert(&me != client_p);
  assert(NULL == client_p->prev);
  assert(NULL == client_p->next);

  if (MyConnect(client_p))
    {
      assert(IsClosing(client_p) && IsDead(client_p));
      
    /*
     * clean up extra sockets from P-lines which have been discarded.
     */
    if (client_p->localClient->listener)
    {
      assert(0 < client_p->localClient->listener->ref_count);
      if (0 == --client_p->localClient->listener->ref_count &&
          !client_p->localClient->listener->active) 
        free_listener(client_p->localClient->listener);
      client_p->localClient->listener = 0;
    }

      if (client_p->localClient->fd >= 0)
	fd_close(client_p->localClient->fd);

      BlockHeapFree(lclient_heap, client_p->localClient);
      --local_client_count;
      assert(local_client_count >= 0);
    }
  else
    {
      --remote_client_count;
    }

  BlockHeapFree(client_heap, client_p);
}
	void UnixStreamSocket::userOnUnixStreamRead()
	{
		MS_TRACE_STD();

		// Be ready to parse more than a single message in a single TCP chunk.
		while (true)
		{
			if (IsClosing())
				return;

			size_t read_len = this->bufferDataLen - this->msgStart;
			char* json_start = nullptr;
			size_t json_len;
			int ns_ret = netstring_read((char*)(this->buffer + this->msgStart), read_len,
				&json_start, &json_len);

			if (ns_ret != 0)
			{
				switch (ns_ret)
				{
					case NETSTRING_ERROR_TOO_SHORT:
						// MS_DEBUG_STD("received netstring is too short, need more data");

						// Check if the buffer is full.
						if (this->bufferDataLen == this->bufferSize)
						{
							// First case: the incomplete message does not begin at position 0 of
							// the buffer, so move the incomplete message to the position 0.
							if (this->msgStart != 0)
							{
								// MS_DEBUG_STD("no more space in the buffer, moving parsed bytes to the beginning of the buffer and waiting for more data");

								std::memmove(this->buffer, this->buffer + this->msgStart, read_len);
								this->msgStart = 0;
								this->bufferDataLen = read_len;
							}
							// Second case: the incomplete message begins at position 0 of the buffer.
							// The message is too big, so discard it.
							else
							{
								MS_ERROR_STD("no more space in the buffer for the unfinished message being parsed, discarding it");

								this->msgStart = 0;
								this->bufferDataLen = 0;
							}
						}
						// Otherwise the buffer is not full, just wait.

						// Exit the parsing loop.
						return;

					case NETSTRING_ERROR_TOO_LONG:
						MS_ERROR_STD("NETSTRING_ERROR_TOO_LONG");
						break;

					case NETSTRING_ERROR_NO_COLON:
						MS_ERROR_STD("NETSTRING_ERROR_NO_COLON");
						break;

					case NETSTRING_ERROR_NO_COMMA:
						MS_ERROR_STD("NETSTRING_ERROR_NO_COMMA");
						break;

					case NETSTRING_ERROR_LEADING_ZERO:
						MS_ERROR_STD("NETSTRING_ERROR_LEADING_ZERO");
						break;

					case NETSTRING_ERROR_NO_LENGTH:
						MS_ERROR_STD("NETSTRING_ERROR_NO_LENGTH");
						break;
				}

				// Error, so reset and exit the parsing loop.
				this->msgStart = 0;
				this->bufferDataLen = 0;

				return;
			}

			// If here it means that json_start points to the beginning of a JSON string
			// with json_len bytes length, so recalculate read_len.
			read_len = (const uint8_t*)json_start - (this->buffer + this->msgStart) + json_len + 1;

			Json::Value json;
			std::string json_parse_error;

			if (this->jsonReader->parse((const char*)json_start, (const char*)json_start + json_len, &json, &json_parse_error))
			{
				Channel::Request* request = nullptr;

				try
				{
					request = new Channel::Request(this, json);
				}
				catch (const MediaSoupError &error)
				{
					MS_ERROR_STD("discarding wrong Channel request");
				}

				if (request)
				{
					// Notify the listener.
					this->listener->onChannelRequest(this, request);

					// Delete the Request.
					delete request;
				}
			}
			else
			{
				MS_ERROR_STD("JSON parsing error: %s", json_parse_error.c_str());
			}

			// If there is no more space available in the buffer and that is because
			// the latest parsed message filled it, then empty the full buffer.
			if ((this->msgStart + read_len) == this->bufferSize)
			{
				// MS_DEBUG_STD("no more space in the buffer, emptying the buffer data");

				this->msgStart = 0;
				this->bufferDataLen = 0;
			}
			// If there is still space in the buffer, set the beginning of the next
			// parsing to the next position after the parsed message.
			else
			{
				this->msgStart += read_len;
			}

			// If there is more data in the buffer after the parsed message
			// then parse again. Otherwise break here and wait for more data.
			if (this->bufferDataLen > this->msgStart)
			{
				// MS_DEBUG_STD("there is more data after the parsed message, continue parsing");

				continue;
			}
			else
			{
				break;
			}
		}
	}
示例#10
0
/*
** exit_client - This is old "m_bye". Name  changed, because this is not a
**        protocol function, but a general server utility function.
**
**        This function exits a client of *any* type (user, server, etc)
**        from this server. Also, this generates all necessary prototol
**        messages that this exit may cause.
**
**   1) If the client is a local client, then this implicitly
**        exits all other clients depending on this connection (e.g.
**        remote clients having 'from'-field that points to this.
**
**   2) If the client is a remote client, then only this is exited.
**
** For convenience, this function returns a suitable value for
** m_function return value:
**
**        CLIENT_EXITED        if (client_p == source_p)
**        0                if (client_p != source_p)
*/
int exit_client(
                struct Client* client_p, /* The local client originating the
                                          * exit or NULL, if this exit is
                                          * generated by this server for
                                          * internal reasons.
                                          * This will not get any of the
                                          * generated messages. */
                struct Client* source_p, /* Client exiting */
                struct Client* from,     /* Client firing off this Exit,
                                          * never NULL! */
                const char* comment      /* Reason for the exit */
               )
{
  char comment1[HOSTLEN + HOSTLEN + 2];
  dlink_node *m;
  fprintf(stderr, "Exiting client: %s\n", comment);
  if (MyConnect(source_p))
    {
      /* DO NOT REMOVE. exit_client can be called twice after a failed
       * read/write.
       */
      if(IsClosing(source_p))
        return 0;

      SetClosing(source_p);
      if (source_p->flags & FLAGS_IPHASH)
        remove_one_ip(&source_p->localClient->ip);

      delete_adns_queries(source_p->localClient->dns_query);
      delete_identd_queries(source_p);
      client_flush_input(source_p);

      /* This source_p could have status of one of STAT_UNKNOWN, STAT_CONNECTING
       * STAT_HANDSHAKE or STAT_UNKNOWN
       * all of which are lumped together into unknown_list
       *
       * In all above cases IsRegistered() will not be true.
       */
      if (!IsRegistered(source_p))
	{
	  m = dlinkFind(&unknown_list,source_p);
	  if(m != NULL)
	    {
	      dlinkDelete(m, &unknown_list);
	      free_dlink_node(m);
	    }
	}
      if (IsOper(source_p))
        {
	  m = dlinkFind(&oper_list,source_p);
	  if(m != NULL)
	    {
	      dlinkDelete(m, &oper_list);
	      free_dlink_node(m);
	    }
        }
      if (IsClient(source_p))
        {
          Count.local--;

          if(IsPerson(source_p))        /* a little extra paranoia */
            {
	      m = dlinkFind(&lclient_list,source_p);
	      if(m != NULL)
		{
		  dlinkDelete(m,&lclient_list);
		  free_dlink_node(m);
		}
            }
        }

      /* As soon as a client is known to be a server of some sort
       * it has to be put on the serv_list, or SJOIN's to this new server
       * from the connect burst will not be seen.
       */
      if (IsServer(source_p) || IsConnecting(source_p) ||
          IsHandshake(source_p))
	{
	  m = dlinkFind(&serv_list,source_p);
	  if(m != NULL)
	    {
	      dlinkDelete(m,&serv_list);
	      free_dlink_node(m);
              unset_chcap_usage_counts(source_p);
	    }
	}

      if (IsServer(source_p))
        {
          Count.myserver--;
	  if(ServerInfo.hub)
	    remove_lazylink_flags(source_p->localClient->serverMask);
	  else
	    uplink = NULL;
        }

      if (IsPerson(source_p))
        sendto_realops_flags(FLAGS_CCONN, L_ALL,
                             "Client exiting: %s (%s@%s) [%s] [%s]",
                             source_p->name, source_p->username, source_p->host,
                             comment, source_p->localClient->sockhost);

      log_user_exit(source_p);

      if (source_p->localClient->fd >= 0)
	{
	  if (client_p != NULL && source_p != client_p)
	    sendto_one(source_p, "ERROR :Closing Link: %s %s (%s)",
		       source_p->host, source_p->name, comment);
	  else
	    sendto_one(source_p, "ERROR :Closing Link: %s (%s)",
		       source_p->host, comment);
	}
      /*
      ** Currently only server connections can have
      ** depending remote clients here, but it does no
      ** harm to check for all local clients. In
      ** future some other clients than servers might
      ** have remotes too...
      **
      ** Close the Client connection first and mark it
      ** so that no messages are attempted to send to it.
      ** (The following *must* make MyConnect(source_p) == FALSE!).
      ** It also makes source_p->from == NULL, thus it's unnecessary
      ** to test whether "source_p != target_p" in the following loops.
      */
     close_connection(source_p);
    }

  if(IsServer(source_p))
    {        
      if(ConfigServerHide.hide_servers)
	{
          /* set netsplit message to "me.name *.split" to still show 
	   * that its a split, but hide the servers splitting
	   */
	  ircsprintf(comment1,"%s *.split", me.name);
	}
      else
	{
	  if((source_p->serv) && (source_p->serv->up))
	    strcpy(comment1, source_p->serv->up);
	  else
	    strcpy(comment1, "<Unknown>");

	  strcat(comment1," ");
	  strcat(comment1, source_p->name);
	}

      remove_dependents(client_p, source_p, from, comment, comment1);

      if (source_p->servptr == &me)
        {
          sendto_realops_flags(FLAGS_ALL, L_ALL,
		       "%s was connected for %d seconds.  %d/%d sendK/recvK.",
			       source_p->name, (int)(CurrentTime - source_p->firsttime),
			       source_p->localClient->sendK,
			       source_p->localClient->receiveK);
          ilog(L_NOTICE, "%s was connected for %d seconds.  %d/%d sendK/recvK.",
              source_p->name, CurrentTime - source_p->firsttime, 
              source_p->localClient->sendK, source_p->localClient->receiveK);
        }
    }
  exit_one_client(client_p, source_p, from, comment);
  return client_p == source_p ? CLIENT_EXITED : 0;
}