Example #1
0
SilcBool silc_server_send_notify(SilcServer server,
				 SilcPacketStream stream,
				 SilcBool broadcast,
				 SilcNotifyType type,
				 SilcUInt32 argc, ...)
{
  va_list ap;
  SilcBuffer packet;
  SilcBool ret = FALSE;

  if (!stream)
    return FALSE;

  va_start(ap, argc);

  packet = silc_notify_payload_encode(type, argc, ap);
  if (!packet) {
    va_end(ap);
    return ret;
  }

  ret = silc_packet_send(stream, SILC_PACKET_NOTIFY,
			 broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
			 packet->data, silc_buffer_len(packet));

#if 0
  /* Send to backup routers if this is being broadcasted to primary
     router.  The silc_server_backup_send checks further whether to
     actually send it or not. */
  if ((broadcast && stream == SILC_PRIMARY_ROUTE(server)) ||
      (broadcast && !SILC_PRIMARY_ROUTE(server)))
    silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
			    packet->data, packet->len, FALSE, TRUE);
#endif /* 0 */

  silc_buffer_free(packet);
  va_end(ap);

  return ret;
}
Example #2
0
static char
silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
{
  SilcServer server = cmd->server;
  SilcUInt32 len, id_len;
  unsigned char *id_data;
  char *name, *info;
  SilcClientID client_id;
  SilcServerID server_id;
  SilcChannelID channel_id;
  SilcClientEntry client;
  SilcServerEntry server_entry;
  SilcChannelEntry channel;
  char global = FALSE;
  char nick[128 + 1];
  SilcIDPayload idp = NULL;
  SilcIdType id_type;

  id_data = silc_argument_get_arg_type(cmd->args, 2, &id_len);
  if (!id_data)
    return FALSE;
  idp = silc_id_payload_parse(id_data, id_len);
  if (!idp)
    return FALSE;

  name = silc_argument_get_arg_type(cmd->args, 3, &len);
  info = silc_argument_get_arg_type(cmd->args, 4, &len);

  id_type = silc_id_payload_get_type(idp);

  switch (id_type) {
  case SILC_ID_CLIENT:
    if (!silc_id_payload_get_id(idp, &client_id, sizeof(client_id)))
      goto error;

    SILC_LOG_DEBUG(("Received client information"));

    client = silc_idlist_find_client_by_id(server->local_list,
					   &client_id, FALSE, NULL);
    if (!client) {
      client = silc_idlist_find_client_by_id(server->global_list, &client_id,
					     FALSE, NULL);
      global = TRUE;
    }
    if (!client) {
      /* If router did not find such Client ID in its lists then this must
	 be bogus client or some router in the net is buggy. */
      if (server->server_type != SILC_SERVER)
	goto error;

      /* Take nickname */
      if (name)
	silc_parse_userfqdn(name, nick, sizeof(nick), NULL, 0);

      /* We don't have that client anywhere, add it. The client is added
	 to global list since server didn't have it in the lists so it must be
	 global. */
      client = silc_idlist_add_client(server->global_list,
				      nick[0] ? strdup(nick) : NULL,
				      info ? strdup(info) : NULL, NULL,
				      silc_id_dup(&client_id, SILC_ID_CLIENT),
				      silc_packet_get_context(cmd->sock),
				      NULL);
      if (!client) {
	SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
	goto error;
      }

      client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
      client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
      client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;

      SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
		      server->stat.clients + 1));
      server->stat.clients++;
    } else {
      /* We have the client already, update the data */

      SILC_LOG_DEBUG(("Updating client data"));

      /* Take nickname */
      if (name) {
	silc_parse_userfqdn(name, nick, sizeof(nick), NULL, 0);

	/* Check nickname */
	name = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8,
				     128, NULL);
	if (!name) {
	  SILC_LOG_ERROR(("Malformed nickname '%s' received in IDENTIFY "
			  "reply ", nick));
	  return FALSE;
	}

	silc_free(client->nickname);
	client->nickname = strdup(nick);

	/* Update the context */
	silc_idcache_update_by_context(global ? server->global_list->clients :
				       server->local_list->clients, client,
				       NULL, name, TRUE);
      }

      if (info) {
	silc_free(client->username);
	client->username = strdup(info);
      }

      client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
      client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
    }

    break;

  case SILC_ID_SERVER:
    if (!name)
      goto error;

    if (!silc_id_payload_get_id(idp, &server_id, sizeof(server_id)))
      goto error;

    SILC_LOG_DEBUG(("Received server information"));

    server_entry = silc_idlist_find_server_by_id(server->local_list,
						 &server_id, FALSE, NULL);
    if (!server_entry)
      server_entry = silc_idlist_find_server_by_id(server->global_list,
						   &server_id, FALSE, NULL);
    if (!server_entry) {
      /* If router did not find such Server ID in its lists then this must
	 be bogus server or some router in the net is buggy. */
      if (server->server_type != SILC_SERVER)
	goto error;

      /* We don't have that server anywhere, add it. */
      server_entry = silc_idlist_add_server(server->global_list,
					    strdup(name), 0,
					    silc_id_dup(&server_id,
							SILC_ID_SERVER),
					    server->router,
					    SILC_PRIMARY_ROUTE(server));
      if (!server_entry)
	goto error;

      server_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
      server_entry->data.status |= SILC_IDLIST_STATUS_RESOLVED;
      server_entry->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
    }

    break;

  case SILC_ID_CHANNEL:
    if (!name)
      goto error;

    if (!silc_id_payload_get_id(idp, &channel_id, sizeof(channel_id)))
      goto error;

    SILC_LOG_DEBUG(("Received channel information"));

    /* Check channel name */
    info = silc_channel_name_check(name, strlen(name), SILC_STRING_UTF8,
				   256, NULL);
    if (!info)
      goto error;

    channel = silc_idlist_find_channel_by_name(server->local_list,
					       info, NULL);
    if (!channel)
      channel = silc_idlist_find_channel_by_name(server->global_list,
						 info, NULL);
    if (!channel) {
      /* If router did not find such Channel ID in its lists then this must
	 be bogus channel or some router in the net is buggy. */
      if (server->server_type != SILC_SERVER) {
	silc_free(info);
	goto error;
      }

      /* We don't have that channel anywhere, add it. */
      channel = silc_idlist_add_channel(server->global_list, strdup(name),
					SILC_CHANNEL_MODE_NONE,
					silc_id_dup(&channel_id,
						    SILC_ID_CHANNEL),
					server->router, NULL, NULL, 0);
      if (!channel) {
	silc_free(info);
	goto error;
      }
      silc_free(info);
    }

    break;
  }

  silc_id_payload_free(idp);
  return TRUE;

 error:
  silc_id_payload_free(idp);
  return FALSE;
}