コード例 #1
0
/**
 * @brief Store the peers currently in #valid_peers to disk.
 */
static void
store_valid_peers ()
{
  struct GNUNET_DISK_FileHandle *fh;
  uint32_t number_written_peers;
  int ret;

  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
  {
    return;
  }

  ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers);
  if (GNUNET_SYSERR == ret)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Not able to create directory for file `%s'\n",
        filename_valid_peers);
    GNUNET_break (0);
  }
  else if (GNUNET_NO == ret)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Directory for file `%s' exists but is not writable for us\n",
        filename_valid_peers);
    GNUNET_break (0);
  }
  fh = GNUNET_DISK_file_open (filename_valid_peers,
                              GNUNET_DISK_OPEN_WRITE |
                                  GNUNET_DISK_OPEN_CREATE,
                              GNUNET_DISK_PERM_USER_READ |
                                  GNUNET_DISK_PERM_USER_WRITE);
  if (NULL == fh)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Not able to write valid peers to file `%s'\n",
        filename_valid_peers);
    return;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
      "Writing %u valid peers to disk\n",
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
  number_written_peers =
    GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
                                           store_peer_presistently_iterator,
                                           fh);
  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
  GNUNET_assert (number_written_peers ==
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
}
コード例 #2
0
/**
 * Handler for CREATE message from client, creates
 * new identity.
 *
 * @param cls unused
 * @param client who sent the message
 * @param message the message received
 */
static void
handle_create_message (void *cls,
                       const struct CreateRequestMessage *crm)
{
  struct GNUNET_SERVICE_Client *client = cls;
  struct Ego *ego;
  const char *str;
  char *fn;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received CREATE message from client\n");
  str = (const char *) &crm[1];
  for (ego = ego_head; NULL != ego; ego = ego->next)
  {
    if (0 == strcmp (ego->identifier,
                     str))
    {
      send_result_code (client, 1, gettext_noop ("identifier already in use for another ego"));
      GNUNET_SERVICE_client_continue (client);
      return;
    }
  }
  ego = GNUNET_new (struct Ego);
  ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
  *ego->pk = crm->private_key;
  ego->identifier = GNUNET_strdup (str);
  GNUNET_CONTAINER_DLL_insert (ego_head,
                               ego_tail,
                               ego);
  send_result_code (client, 0, NULL);
  fn = get_ego_filename (ego);
  (void) GNUNET_DISK_directory_create_for_file (fn);
  if (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) !=
      GNUNET_DISK_fn_write (fn,
                            &crm->private_key,
                            sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
                            GNUNET_DISK_PERM_USER_READ |
                            GNUNET_DISK_PERM_USER_WRITE))
    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                              "write", fn);
  GNUNET_free (fn);
  notify_listeners (ego);
  GNUNET_SERVICE_client_continue (client);
}
コード例 #3
0
/**
 * Bind a host address (hello) to a hostId.
 *
 * @param peer the peer for which this is a hello
 * @param hello the verified (!) hello message
 */
static void
bind_address (const struct GNUNET_PeerIdentity *peer,
              const struct GNUNET_HELLO_Message *hello)
{
  char *fn;
  struct HostEntry *host;
  struct GNUNET_HELLO_Message *mrg;
  struct GNUNET_TIME_Absolute delta;

  add_host_to_known_hosts (peer);
  host = GNUNET_CONTAINER_multihashmap_get (hostmap, &peer->hashPubKey);
  GNUNET_assert (host != NULL);
  if (host->hello == NULL)
  {
    host->hello = GNUNET_malloc (GNUNET_HELLO_size (hello));
    memcpy (host->hello, hello, GNUNET_HELLO_size (hello));
  }
  else
  {
    mrg = GNUNET_HELLO_merge (host->hello, hello);
    delta = GNUNET_HELLO_equals (mrg, host->hello, GNUNET_TIME_absolute_get ());
    if (delta.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
    {
      GNUNET_free (mrg);
      return;
    }
    GNUNET_free (host->hello);
    host->hello = mrg;
  }
  fn = get_host_filename (peer);
  if (GNUNET_OK == GNUNET_DISK_directory_create_for_file (fn))
  {
    if (GNUNET_SYSERR ==
        GNUNET_DISK_fn_write (fn, host->hello, GNUNET_HELLO_size (host->hello),
                              GNUNET_DISK_PERM_USER_READ |
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_GROUP_READ |
                              GNUNET_DISK_PERM_OTHER_READ))
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);

  }
  GNUNET_free (fn);
  notify_all (host);
}
コード例 #4
0
ファイル: test_disk.c プロジェクト: tg-x/gnunet
static int
testDirMani ()
{
  if (GNUNET_OK != GNUNET_DISK_directory_create_for_file ("test/ing"))
    return 1;
  if (GNUNET_NO != GNUNET_DISK_file_test ("test"))
    return 1;
  if (GNUNET_NO != GNUNET_DISK_file_test ("test/ing"))
    return 1;
  if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
    return 1;
  if (GNUNET_OK != GNUNET_DISK_directory_create ("test"))
    return 1;
  if (GNUNET_YES != GNUNET_DISK_directory_test ("test", GNUNET_YES))
    return 1;
  if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
    return 1;


  return 0;
}
コード例 #5
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *filename;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-sqlite",
                                               "FILENAME", &filename))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-sqlite",
                               "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (filename))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (filename))
    {
      GNUNET_break (0);
      GNUNET_free (filename);
      return GNUNET_SYSERR;
    }
  }
  /* filename should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = filename;
  /* Open database and precompile statements */
  if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize SQLite: %s.\n"),
         sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY");
  sql_exec (plugin->dbh, "PRAGMA synchronous=OFF");
  sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF");
  sql_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL");
  sql_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"");
  sql_exec (plugin->dbh, "PRAGMA page_size=4096");
  sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS);
  /* Create tables */
  sql_exec (plugin->dbh,
            "CREATE TABLE IF NOT EXISTS peerstoredata (\n"
            "  sub_system TEXT NOT NULL,\n" "  peer_id BLOB NOT NULL,\n"
            "  key TEXT NOT NULL,\n" "  value BLOB NULL,\n"
            "  expiry sqlite3_uint64 NOT NULL" ");");
  sqlite3_create_function (plugin->dbh, "UINT64_LT", 2, SQLITE_UTF8, NULL,
                           &sqlite3_lessthan, NULL, NULL);
  /* Create Indices */
  if (SQLITE_OK !=
      sqlite3_exec (plugin->dbh,
                    "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)",
                    NULL, NULL, NULL))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to create indices: %s.\n"),
         sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  /* Prepare statements */

  sql_prepare (plugin->dbh,
               "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry) VALUES (?,?,?,?,?);",
               &plugin->insert_peerstoredata);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?",
               &plugin->select_peerstoredata);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?", &plugin->select_peerstoredata_by_pid);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND key = ?", &plugin->select_peerstoredata_by_key);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?" " AND key = ?",
               &plugin->select_peerstoredata_by_all);
  sql_prepare (plugin->dbh,
               "DELETE FROM peerstoredata" " WHERE UINT64_LT(expiry, ?)",
               &plugin->expire_peerstoredata);
  sql_prepare (plugin->dbh,
               "DELETE FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?" " AND key = ?",
               &plugin->delete_peerstoredata);
  return GNUNET_OK;
}
コード例 #6
0
ファイル: gnunet-service-identity.c プロジェクト: tg-x/gnunet
/**
 * Handler for CREATE message from client, creates
 * new identity.
 *
 * @param cls unused
 * @param client who sent the message
 * @param message the message received
 */
static void
handle_create_message (void *cls, struct GNUNET_SERVER_Client *client,
		       const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_IDENTITY_CreateRequestMessage *crm;
  uint16_t size;
  uint16_t name_len;
  struct Ego *ego;
  const char *str;
  char *fn;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Received CREATE message from client\n");
  size = ntohs (message->size);
  if (size <= sizeof (struct GNUNET_IDENTITY_CreateRequestMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  crm = (const struct GNUNET_IDENTITY_CreateRequestMessage *) message;
  name_len = ntohs (crm->name_len);
  GNUNET_break (0 == ntohs (crm->reserved));
  if (name_len + sizeof (struct GNUNET_IDENTITY_CreateRequestMessage) != size)
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  str = (const char *) &crm[1];
  if ('\0' != str[name_len - 1])
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  for (ego = ego_head; NULL != ego; ego = ego->next)
  {
    if (0 == strcmp (ego->identifier,
		     str))
    {
      send_result_code (client, 1, gettext_noop ("identifier already in use for another ego"));
      GNUNET_SERVER_receive_done (client, GNUNET_OK);
      return;
    }
  }
  ego = GNUNET_new (struct Ego);
  ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
  *ego->pk = crm->private_key;
  ego->identifier = GNUNET_strdup (str);
  GNUNET_CONTAINER_DLL_insert (ego_head,
			       ego_tail,
			       ego);
  send_result_code (client, 0, NULL);
  fn = get_ego_filename (ego);
  (void) GNUNET_DISK_directory_create_for_file (fn);
  if (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) !=
      GNUNET_DISK_fn_write (fn,
			    &crm->private_key,
			    sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
			    GNUNET_DISK_PERM_USER_READ |
			    GNUNET_DISK_PERM_USER_WRITE))
    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
			      "write", fn);
  GNUNET_free (fn);
  notify_listeners (ego);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
コード例 #7
0
ファイル: client.c プロジェクト: muggenhor/GNUnet
/**
 * Test if the service is running.  If we are given a UNIXPATH or a
 * local address, we do this NOT by trying to connect to the service,
 * but by trying to BIND to the same port.  If the BIND fails, we know
 * the service is running.
 *
 * @param service name of the service to wait for
 * @param cfg configuration to use
 * @param timeout how long to wait at most
 * @param cb function to call with the result
 * @param cb_cls closure for @a cb
 * @return handle to cancel the test
 */
struct GNUNET_CLIENT_TestHandle *
GNUNET_CLIENT_service_test (const char *service,
                            const struct GNUNET_CONFIGURATION_Handle *cfg,
                            struct GNUNET_TIME_Relative timeout,
                            GNUNET_CLIENT_TestResultCallback cb,
			    void *cb_cls)
{
  struct GNUNET_CLIENT_TestHandle *th;
  char *hostname;
  unsigned long long port;
  struct GNUNET_NETWORK_Handle *sock;

  th = GNUNET_new (struct GNUNET_CLIENT_TestHandle);
  th->cb = cb;
  th->cb_cls = cb_cls;
  th->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Testing if service `%s' is running.\n",
       service);
#ifdef AF_UNIX
  {
    /* probe UNIX support */
    struct sockaddr_un s_un;
    char *unixpath;
    int abstract;

    unixpath = NULL;
    if ((GNUNET_OK ==
	 GNUNET_CONFIGURATION_get_value_filename (cfg,
						  service,
						  "UNIXPATH",
						  &unixpath)) &&
	(0 < strlen (unixpath)))  /* We have a non-NULL unixpath, does that mean it's valid? */
    {
      if (strlen (unixpath) >= sizeof (s_un.sun_path))
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             _("UNIXPATH `%s' too long, maximum length is %llu\n"),
	     unixpath,
             (unsigned long long) sizeof (s_un.sun_path));
	unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
        LOG (GNUNET_ERROR_TYPE_INFO,
             _("Using `%s' instead\n"), unixpath);
      }
    }
#ifdef LINUX
    abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
                                                     "TESTING",
                                                     "USE_ABSTRACT_SOCKETS");
#else
    abstract = GNUNET_NO;
#endif
    if ((NULL != unixpath) && (GNUNET_YES != abstract))
    {
      if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (unixpath))
        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                  "mkdir", unixpath);
    }
    if (NULL != unixpath)
    {
      sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
      if (NULL != sock)
      {
	memset (&s_un, 0, sizeof (s_un));
	s_un.sun_family = AF_UNIX;
        strncpy (s_un.sun_path, unixpath, sizeof (s_un.sun_path) - 1);
        if (GNUNET_YES == abstract)
          s_un.sun_path[0] = '\0';
#if HAVE_SOCKADDR_IN_SIN_LEN
        s_un.sun_len = (u_char) sizeof (struct sockaddr_un);
#endif
	if (GNUNET_OK !=
	    GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un,
					sizeof (struct sockaddr_un)))
        {
	  /* failed to bind => service must be running */
	  GNUNET_free (unixpath);
	  (void) GNUNET_NETWORK_socket_close (sock);
	  service_test_report (th, GNUNET_YES);
	  return th;
	}
	(void) GNUNET_NETWORK_socket_close (sock);
        /* let's try IP */
      }
    }
    GNUNET_free_non_null (unixpath);
  }
#endif

  hostname = NULL;
  if ((GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_number (cfg, service, "PORT", &port)) ||
      (port > 65535) ||
      (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME",
                                              &hostname)))
  {
    /* UNIXPATH failed (if possible) AND IP failed => error */
    service_test_report (th, GNUNET_SYSERR);
    return th;
  }

  if (0 == strcmp ("localhost", hostname)
#if !LINUX
      && 0
#endif
      )
  {
    /* can test using 'bind' */
    struct sockaddr_in s_in;

    memset (&s_in, 0, sizeof (s_in));
#if HAVE_SOCKADDR_IN_SIN_LEN
    s_in.sin_len = sizeof (struct sockaddr_in);
#endif
    s_in.sin_family = AF_INET;
    s_in.sin_port = htons (port);

    sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
    if (NULL != sock)
    {
      if (GNUNET_OK !=
          GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in,
                                      sizeof (s_in)))
      {
        /* failed to bind => service must be running */
        GNUNET_free (hostname);
        (void) GNUNET_NETWORK_socket_close (sock);
        service_test_report (th, GNUNET_YES);
        return th;
      }
      (void) GNUNET_NETWORK_socket_close (sock);
    }
  }

  if (0 == strcmp ("ip6-localhost", hostname)
#if !LINUX
      && 0
#endif
      )
  {
    /* can test using 'bind' */
    struct sockaddr_in6 s_in6;

    memset (&s_in6, 0, sizeof (s_in6));
#if HAVE_SOCKADDR_IN_SIN_LEN
    s_in6.sin6_len = sizeof (struct sockaddr_in6);
#endif
    s_in6.sin6_family = AF_INET6;
    s_in6.sin6_port = htons (port);

    sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
    if (NULL != sock)
    {
      if (GNUNET_OK !=
          GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6,
                                      sizeof (s_in6)))
      {
        /* failed to bind => service must be running */
        GNUNET_free (hostname);
        (void) GNUNET_NETWORK_socket_close (sock);
        service_test_report (th, GNUNET_YES);
        return th;
      }
      (void) GNUNET_NETWORK_socket_close (sock);
    }
  }

  if (((0 == strcmp ("localhost", hostname)) ||
       (0 == strcmp ("ip6-localhost", hostname)))
#if !LINUX
      && 0
#endif
      )
  {
    /* all binds succeeded => claim service not running right now */
    GNUNET_free_non_null (hostname);
    service_test_report (th, GNUNET_NO);
    return th;
  }
  GNUNET_free_non_null (hostname);

  /* non-localhost, try 'connect' method */
  th->client = GNUNET_CLIENT_connect (service, cfg);
  if (NULL == th->client)
  {
    LOG (GNUNET_ERROR_TYPE_INFO,
         _("Could not connect to service `%s', configuration broken.\n"),
         service);
    service_test_report (th, GNUNET_SYSERR);
    return th;
  }
  th->th = GNUNET_CLIENT_notify_transmit_ready (th->client,
						sizeof (struct GNUNET_MessageHeader),
						timeout, GNUNET_YES,
						&write_test, th);
  if (NULL == th->th)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         _("Failure to transmit request to service `%s'\n"), service);
    service_test_report (th, GNUNET_SYSERR);
    return th;
  }
  return th;
}
コード例 #8
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return #GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  sqlite3_stmt *stmt;
  char *afsdir;
#if ENULL_DEFINED
  char *e;
#endif

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namecache-sqlite",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "namecache-sqlite", "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
  }
  /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = afsdir;

  /* Open database and precompile statements */
  if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
  {
    LOG (GNUNET_ERROR_TYPE_ERROR,
	 _("Unable to initialize SQLite: %s.\n"),
	 sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA synchronous=NORMAL", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
                       NULL, ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"", NULL,
                       NULL, ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
                       ENULL));

  CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));


  /* Create tables */
  CHECK (SQLITE_OK ==
         sq_prepare (plugin->dbh,
                     "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096blocks'",
                     &stmt));
  if ((sqlite3_step (stmt) == SQLITE_DONE) &&
      (sqlite3_exec
       (plugin->dbh,
        "CREATE TABLE ns096blocks ("
        " query BLOB NOT NULL DEFAULT '',"
        " block BLOB NOT NULL DEFAULT '',"
        " expiration_time INT8 NOT NULL DEFAULT 0"
	")",
	NULL, NULL, NULL) != SQLITE_OK))
  {
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
    sqlite3_finalize (stmt);
    return GNUNET_SYSERR;
  }
  sqlite3_finalize (stmt);
  create_indices (plugin->dbh);

  if ((sq_prepare
       (plugin->dbh,
        "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, ?)",
        &plugin->cache_block) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "DELETE FROM ns096blocks WHERE expiration_time<?",
        &plugin->expire_blocks) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "DELETE FROM ns096blocks WHERE query=? AND expiration_time<=?",
        &plugin->delete_block) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time DESC LIMIT 1",
        &plugin->lookup_block) != SQLITE_OK)
      )
  {
    LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling");
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}
コード例 #9
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param cfg our configuration
 * @param plugin the plugin context (state for this module)
 * @return GNUNET_OK on success
 */
static int
database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
                struct Plugin *plugin)
{
  sqlite3_stmt *stmt;
  char *afsdir;

#if ENULL_DEFINED
  char *e;
#endif

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "datastore-sqlite",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite",
                     _
                     ("Option `%s' in section `%s' missing in configuration!\n"),
                     "FILENAME", "datastore-sqlite");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
    /* database is new or got deleted, reset payload to zero! */
    plugin->env->duc (plugin->env->cls, 0);
  }
#ifdef ENABLE_NLS
  plugin->fn =
      GNUNET_STRINGS_to_utf8 (afsdir, strlen (afsdir), nl_langinfo (CODESET));
#else
  plugin->fn = GNUNET_STRINGS_to_utf8 (afsdir, strlen (afsdir), "UTF-8");       /* good luck */
#endif
  GNUNET_free (afsdir);

  /* Open database and precompile statements */
  if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite",
                     _("Unable to initialize SQLite: %s.\n"),
                     sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA synchronous=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
                       NULL, ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA count_changes=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
                       ENULL));

  CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));


  /* We have to do it here, because otherwise precompiling SQL might fail */
  CHECK (SQLITE_OK ==
         sq_prepare (plugin->dbh,
                     "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn090'",
                     &stmt));
  if ((sqlite3_step (stmt) == SQLITE_DONE) &&
      (sqlite3_exec
       (plugin->dbh,
        "CREATE TABLE gn090 (" "  repl INT4 NOT NULL DEFAULT 0,"
        "  type INT4 NOT NULL DEFAULT 0," "  prio INT4 NOT NULL DEFAULT 0,"
        "  anonLevel INT4 NOT NULL DEFAULT 0,"
        "  expire INT8 NOT NULL DEFAULT 0," "  rvalue INT8 NOT NULL,"
        "  hash TEXT NOT NULL DEFAULT ''," "  vhash TEXT NOT NULL DEFAULT '',"
        "  value BLOB NOT NULL DEFAULT '')", NULL, NULL, NULL) != SQLITE_OK))
  {
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
    sqlite3_finalize (stmt);
    return GNUNET_SYSERR;
  }
  sqlite3_finalize (stmt);
  create_indices (plugin->dbh);

  if ((sq_prepare
       (plugin->dbh,
        "UPDATE gn090 "
        "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?",
        &plugin->updPrio) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?",
        &plugin->updRepl) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_repl_rvalue "
#endif
        "WHERE repl=?2 AND " " (rvalue>=?1 OR "
        "  NOT EXISTS (SELECT 1 FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_repl_rvalue "
#endif
        "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) "
        "ORDER BY rvalue ASC LIMIT 1", &plugin->selRepl) != SQLITE_OK) ||
      (sq_prepare (plugin->dbh, "SELECT MAX(repl) FROM gn090"
#if SQLITE_VERSION_NUMBER >= 3007000
                   " INDEXED BY idx_repl_rvalue"
#endif
                   "", &plugin->maxRepl) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_expire "
#endif
        "WHERE NOT EXISTS (SELECT 1 FROM gn090 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) "
        "ORDER BY expire ASC LIMIT 1", &plugin->selExpi) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_anon_type_hash "
#endif
        "WHERE (anonLevel = 0 AND type=?1) "
        "ORDER BY hash DESC LIMIT 1 OFFSET ?2",
        &plugin->selZeroAnon) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
        "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
        &plugin->insertContent) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh, "DELETE FROM gn090 WHERE _ROWID_ = ?",
        &plugin->delRow) != SQLITE_OK))
  {
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "precompiling");
    return GNUNET_SYSERR;
  }

  return GNUNET_OK;
}
コード例 #10
0
/**
 * Main function of a program that pretends to be a WLAN card.
 *
 * @param argc should be 2
 * @param argv either '1' or '2', depending on which of the two cards this dummy is to emulate
 * @return 1 on error, 0 if terminated normally via signal
 */
int
main (int argc, char *argv[])
{
  struct stat st;
  int erg;
  FILE *fpin = NULL;
  FILE *fpout = NULL;
  int fdpin;
  int fdpout;
  char readbuf[MAXLINE];
  int readsize;
  struct SendBuffer write_std;
  struct SendBuffer write_pout;
  int ret;
  int maxfd;
  fd_set rfds;
  fd_set wfds;
  struct timeval tv;
  int retval;
  struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst = NULL;
  struct GNUNET_SERVER_MessageStreamTokenizer *file_in_mst = NULL;
  struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr;
  int first;

  if ( (2 != argc) ||
       ((0 != strcmp (argv[1], "1")) && (0 != strcmp (argv[1], "2"))) )
  {
    FPRINTF (stderr,
             "%s",
	     "This program must be started with the operating mode (1 or 2) as the only argument.\n");
    return 1;
  }

  /* make the fifos if needed */
  umask (0);
  if ( (GNUNET_OK != GNUNET_DISK_directory_create_for_file (FIFO_FILE1)) ||
       (GNUNET_OK != GNUNET_DISK_directory_create_for_file (FIFO_FILE2)) )
  {
    FPRINTF (stderr, "Failed to create directory for file `%s'\n", FIFO_FILE1);
    return 1;
  }
  if (0 == strcmp (argv[1], "1") )
  {
    if (0 != stat (FIFO_FILE1, &st))
    {
      erg = mkfifo (FIFO_FILE1, 0666);
      if ( (0 != erg) && (EEXIST != errno) )
	FPRINTF (stderr, "Error in mkfifo(%s): %s\n", FIFO_FILE1,
		 strerror (errno));    
    }
  }
  else
  {
    if (0 != stat (FIFO_FILE2, &st))
    {
      erg = mkfifo (FIFO_FILE2, 0666);
      if ( (0 != erg) && (EEXIST != errno) )
	FPRINTF (stderr, "Error in mkfifo(%s): %s\n", FIFO_FILE2,
		 strerror (errno));
    }
  }

  if (0 == strcmp (argv[1], "1"))
  {
    first = 1;
    fpin = fopen (FIFO_FILE1, "r");
    if (NULL == fpin)
    {
      FPRINTF (stderr, "fopen of read FIFO_FILE1 failed: %s\n", STRERROR (errno));
      goto end;
    }
    if (NULL == (fpout = fopen (FIFO_FILE2, "w")))
    {
      erg = mkfifo (FIFO_FILE2, 0666);
      fpout = fopen (FIFO_FILE2, "w");
    }
    if (NULL == fpout)
    {
      FPRINTF (stderr, "fopen of write FIFO_FILE2 failed: %s\n", STRERROR (errno));
      goto end;
    }
  }
  else
  {
    first = 0;
    if (NULL == (fpout = fopen (FIFO_FILE1, "w")))
    {
      erg = mkfifo (FIFO_FILE1, 0666);
      fpout = fopen (FIFO_FILE1, "w");
    }
    if (NULL == fpout)
    {
      FPRINTF (stderr, "fopen of write FIFO_FILE1 failed: %s\n", STRERROR (errno));
      goto end;
    }
    fpin = fopen (FIFO_FILE2, "r");
    if (NULL == fpin)
    {
      FPRINTF (stderr, "fopen of read FIFO_FILE2 failed: %s\n", STRERROR (errno));
      goto end;
    }
  }

  fdpin = fileno (fpin);
  GNUNET_assert (fpin >= 0);
  if (fdpin >= FD_SETSIZE)
  {
    FPRINTF (stderr, "File fdpin number too large (%d > %u)\n", fdpin,
             (unsigned int) FD_SETSIZE);
    goto end;
  }

  fdpout = fileno (fpout);
  GNUNET_assert (fdpout >= 0);

  if (fdpout >= FD_SETSIZE)
  {
    FPRINTF (stderr, "File fdpout number too large (%d > %u)\n", fdpout,
             (unsigned int) FD_SETSIZE);
    goto end;
  }

  signal (SIGINT, &sigfunc);
  signal (SIGTERM, &sigfunc);

  write_std.size = 0;
  write_std.pos = 0;
  write_pout.size = 0;
  write_pout.pos = 0;
  stdin_mst = GNUNET_SERVER_mst_create (&stdin_send, &write_pout);
  file_in_mst = GNUNET_SERVER_mst_create (&file_in_send, &write_std);

  /* Send 'random' mac address */
  macaddr.mac[0] = 0x13;
  macaddr.mac[1] = 0x22;
  macaddr.mac[2] = 0x33;
  macaddr.mac[3] = 0x44;
  macaddr.mac[4] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, 256);
  macaddr.mac[5] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 256);
  write_std.size = send_mac_to_plugin (write_std.buf, &macaddr);

  while (0 == closeprog)
  {
    maxfd = -1;
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    FD_ZERO (&rfds);
    FD_ZERO (&wfds);
    /* if output queue is empty, read */
    if (0 == write_pout.size)
    {
      FD_SET (STDIN_FILENO, &rfds);
      maxfd = MAX (STDIN_FILENO, maxfd);
    }
    if (0 == write_std.size)
    {
      FD_SET (fdpin, &rfds);
      maxfd = MAX (fdpin, maxfd);
    }

    /* if there is something to write, try to write */
    if (0 < write_std.size)
    {
      FD_SET (STDOUT_FILENO, &wfds);
      maxfd = MAX (maxfd, STDOUT_FILENO);
    }
    if (0 < write_pout.size)
    {
      FD_SET (fdpout, &wfds);
      maxfd = MAX (maxfd, fdpout);
    }

    retval = select (maxfd + 1, &rfds, &wfds, NULL, &tv);
    if ((-1 == retval) && (EINTR == errno))
      continue;
    if (0 > retval)
    {
      FPRINTF (stderr, "select failed: %s\n", STRERROR (errno));
      closeprog = 1;
      break;
    }

    if (FD_ISSET (STDOUT_FILENO, &wfds))
    {
      ret =
          write (STDOUT_FILENO, write_std.buf + write_std.pos,
                 write_std.size - write_std.pos);
      if (0 > ret)
      {
        closeprog = 1;
        FPRINTF (stderr, "Write ERROR to STDOUT_FILENO: %s\n",
                 STRERROR (errno));
        break;
      }
      else
      {
        write_std.pos += ret;
        /* check if finished writing */
        if (write_std.pos == write_std.size)
        {
          write_std.pos = 0;
          write_std.size = 0;
        }
      }
    }

    if (FD_ISSET (fdpout, &wfds))
    {
      ret =
          write (fdpout, write_pout.buf + write_pout.pos,
                 write_pout.size - write_pout.pos);

      if (0 > ret)
      {
        closeprog = 1;
        FPRINTF (stderr, "Write ERROR to fdpout failed: %s\n", STRERROR (errno));
      }
      else
      {
        write_pout.pos += ret;
        /* check if finished writing */
        if (write_pout.pos == write_pout.size)
        {
          write_pout.pos = 0;
          write_pout.size = 0;
        }
      }
    }

    if (FD_ISSET (STDIN_FILENO, &rfds))
    {
      readsize = read (STDIN_FILENO, readbuf, sizeof (readbuf));

      if (0 > readsize)
      {
        closeprog = 1;
        FPRINTF (stderr, "Error reading from STDIN_FILENO: %s\n",
                 STRERROR (errno));
      }
      else if (0 < readsize)
      {
        GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, readsize,
                                   GNUNET_NO, GNUNET_NO);

      }
      else
      {
        /* eof */
        closeprog = 1;
      }
    }

    if (FD_ISSET (fdpin, &rfds))
    {
      readsize = read (fdpin, readbuf, sizeof (readbuf));
      if (0 > readsize)
      {
        closeprog = 1;
        FPRINTF (stderr, "Error reading from fdpin: %s\n", STRERROR (errno));
        break;
      }
      else if (0 < readsize)
      {
        GNUNET_SERVER_mst_receive (file_in_mst, NULL, readbuf, readsize,
                                   GNUNET_NO, GNUNET_NO);
      }
      else
      {
        /* eof */
        closeprog = 1;
      }
    }
  }

end:
  /* clean up */
  if (NULL != stdin_mst)
    GNUNET_SERVER_mst_destroy (stdin_mst);
  if (NULL != file_in_mst)
    GNUNET_SERVER_mst_destroy (file_in_mst);

  if (NULL != fpout)
    fclose (fpout);
  if (NULL != fpin)
    fclose (fpin);
  if (1 == first)
  {
    (void) unlink (FIFO_FILE1);
    (void) unlink (FIFO_FILE2);
  }
  return 0;
}
コード例 #11
0
ファイル: crypto_ecc_setup.c プロジェクト: muggenhor/GNUnet
/**
 * Create a new private key by reading it from a file.  If the
 * files does not exist, create a new key and write it to the
 * file.  Caller must free return value.  Note that this function
 * can not guarantee that another process might not be trying
 * the same operation on the same file at the same time.
 * If the contents of the file
 * are invalid the old file is deleted and a fresh key is
 * created.
 *
 * @param filename name of file to use to store the key
 * @return new private key, NULL on error (for example,
 *   permission denied)
 */
struct GNUNET_CRYPTO_EddsaPrivateKey *
GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename)
{
  struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
  struct GNUNET_DISK_FileHandle *fd;
  unsigned int cnt;
  int ec;
  uint64_t fs;

  if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
    return NULL;
  while (GNUNET_YES != GNUNET_DISK_file_test (filename))
  {
    fd = GNUNET_DISK_file_open (filename,
                                GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE
                                | GNUNET_DISK_OPEN_FAILIFEXISTS,
                                GNUNET_DISK_PERM_USER_READ |
                                GNUNET_DISK_PERM_USER_WRITE);
    if (NULL == fd)
    {
      if (EEXIST == errno)
      {
        if (GNUNET_YES != GNUNET_DISK_file_test (filename))
        {
          /* must exist but not be accessible, fail for good! */
          if (0 != ACCESS (filename, R_OK))
            LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
          else
            GNUNET_break (0);   /* what is going on!? */
          return NULL;
        }
        continue;
      }
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
      return NULL;
    }
    cnt = 0;
    while (GNUNET_YES !=
           GNUNET_DISK_file_lock (fd, 0,
                                  sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                                  GNUNET_YES))
    {
      short_wait ();
      if (0 == ++cnt % 10)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
      }
    }
    LOG (GNUNET_ERROR_TYPE_INFO,
         _("Creating a new private key.  This may take a while.\n"));
    priv = GNUNET_CRYPTO_eddsa_key_create ();
    GNUNET_assert (NULL != priv);
    GNUNET_assert (sizeof (*priv) ==
                   GNUNET_DISK_file_write (fd, priv, sizeof (*priv)));
    GNUNET_DISK_file_sync (fd);
    if (GNUNET_YES !=
        GNUNET_DISK_file_unlock (fd, 0,
                                 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
    GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
    return priv;
  }
  /* key file exists already, read it! */
  fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                              GNUNET_DISK_PERM_NONE);
  if (NULL == fd)
  {
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
    return NULL;
  }
  cnt = 0;
  while (1)
  {
    if (GNUNET_YES !=
        GNUNET_DISK_file_lock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                               GNUNET_NO))
    {
      if (0 == ++cnt % 60)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _
             ("This may be ok if someone is currently generating a private key.\n"));
      }
      short_wait ();
      continue;
    }
    if (GNUNET_YES != GNUNET_DISK_file_test (filename))
    {
      /* eh, what!? File we opened is now gone!? */
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));

      return NULL;
    }
    if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
      fs = 0;
    if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))
    {
      /* maybe we got the read lock before the key generating
       * process had a chance to get the write lock; give it up! */
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      if (0 == ++cnt % 10)
      {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"),
             filename, (unsigned int) fs,
             (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("This may be ok if someone is currently generating a key.\n"));
      }
      short_wait ();                /* wait a bit longer! */
      continue;
    }
    break;
  }
  fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey);
  priv = GNUNET_malloc (fs);
  GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs));
  if (GNUNET_YES !=
      GNUNET_DISK_file_unlock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
  GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
  return priv;
}
コード例 #12
0
ファイル: plugin_peerstore_flat.c プロジェクト: GNUnet/gnunet
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *afsdir;
  char *key;
  char *sub_system;
  const char *peer_id;
  char *peer;
  char *value;
  char *expiry;
  struct GNUNET_DISK_FileHandle *fh;
  struct GNUNET_PEERSTORE_Record *entry;
  struct GNUNET_HashCode hkey;
  size_t size;
  char *buffer;
  char *line;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-flat",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-flat",
                               "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
  }
  /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = afsdir;

  fh = GNUNET_DISK_file_open (afsdir,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to initialize file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  /* Load data from file into hashmap */
  plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
                                                     GNUNET_NO);

  if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir,
                                              &size,
                                              GNUNET_YES,
                                              GNUNET_YES))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to get filesize: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  buffer = GNUNET_malloc (size + 1);

  if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh,
                                              buffer,
                                              size))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to read file: %s.\n"),
                afsdir);
    GNUNET_DISK_file_close (fh);
    GNUNET_free (buffer);
    return GNUNET_SYSERR;
  }
  
  buffer[size] = '\0';
  GNUNET_DISK_file_close (fh);
  if (0 < size) {
    line = strtok (buffer, "\n");
    while (line != NULL) {
      sub_system = strtok (line, ",");
      if (NULL == sub_system)
        break;
      peer = strtok (NULL, ",");
      if (NULL == peer)
        break;
      key = strtok (NULL, ",");
      if (NULL == key)
        break;
      value = strtok (NULL, ",");
      if (NULL == value)
        break;
      expiry = strtok (NULL, ",");
      if (NULL == expiry)
        break;
      entry = GNUNET_new (struct GNUNET_PEERSTORE_Record);
      entry->sub_system = GNUNET_strdup (sub_system);
      entry->key = GNUNET_strdup (key);
      GNUNET_STRINGS_base64_decode (peer,
                                    strlen (peer),
                                    (char**)&entry->peer);
      entry->value_size = GNUNET_STRINGS_base64_decode (value,
                                                        strlen (value),
                                                        (char**)&entry->value);
      if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_time_to_absolute (expiry,
                                             entry->expiry))
      {
        GNUNET_free (entry->sub_system);
        GNUNET_free (entry->key);
        GNUNET_free (entry->peer);
        GNUNET_free (entry);
        break;
      }
      peer_id = GNUNET_i2s (entry->peer);
      GNUNET_CRYPTO_hash (peer_id,
                          strlen (peer_id),
                          &hkey);

      GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (plugin->hm,
                                         &hkey,
                                         entry,
                                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));

    }
  }
コード例 #13
0
ファイル: service.c プロジェクト: tg-x/gnunet
/**
 * Get the list of addresses that a server for the given service
 * should bind to.
 *
 * @param service_name name of the service
 * @param cfg configuration (which specifies the addresses)
 * @param addrs set (call by reference) to an array of pointers to the
 *              addresses the server should bind to and listen on; the
 *              array will be NULL-terminated (on success)
 * @param addr_lens set (call by reference) to an array of the lengths
 *              of the respective `struct sockaddr` struct in the @a addrs
 *              array (on success)
 * @return number of addresses found on success,
 *              #GNUNET_SYSERR if the configuration
 *              did not specify reasonable finding information or
 *              if it specified a hostname that could not be resolved;
 *              #GNUNET_NO if the number of addresses configured is
 *              zero (in this case, `*addrs` and `*addr_lens` will be
 *              set to NULL).
 */
int
GNUNET_SERVICE_get_server_addresses (const char *service_name,
                                     const struct GNUNET_CONFIGURATION_Handle *cfg,
                                     struct sockaddr ***addrs,
                                     socklen_t ** addr_lens)
{
  int disablev6;
  struct GNUNET_NETWORK_Handle *desc;
  unsigned long long port;
  char *unixpath;
  struct addrinfo hints;
  struct addrinfo *res;
  struct addrinfo *pos;
  struct addrinfo *next;
  unsigned int i;
  int resi;
  int ret;
  int abstract;
  struct sockaddr **saddrs;
  socklen_t *saddrlens;
  char *hostname;

  *addrs = NULL;
  *addr_lens = NULL;
  desc = NULL;
  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
  {
    if (GNUNET_SYSERR ==
        (disablev6 =
         GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
      return GNUNET_SYSERR;
  }
  else
    disablev6 = GNUNET_NO;

  if (! disablev6)
  {
    /* probe IPv6 support */
    desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
    if (NULL == desc)
    {
      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
          (EACCES == errno))
      {
        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
        return GNUNET_SYSERR;
      }
      LOG (GNUNET_ERROR_TYPE_INFO,
           _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
           service_name, STRERROR (errno));
      disablev6 = GNUNET_YES;
    }
    else
    {
      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
      desc = NULL;
    }
  }

  port = 0;
  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
  {
    if (GNUNET_OK !=
	GNUNET_CONFIGURATION_get_value_number (cfg, service_name,
					       "PORT", &port))
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Require valid port number for service `%s' in configuration!\n"),
           service_name);
    }
    if (port > 65535)
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Require valid port number for service `%s' in configuration!\n"),
           service_name);
      return GNUNET_SYSERR;
    }
  }

  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
  {
    GNUNET_break (GNUNET_OK ==
                  GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
                                                         "BINDTO", &hostname));
  }
  else
    hostname = NULL;

  unixpath = NULL;
  abstract = GNUNET_NO;
#ifdef AF_UNIX
  if ((GNUNET_YES ==
       GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
      (GNUNET_OK ==
       GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH",
                                              &unixpath)) &&
      (0 < strlen (unixpath)))
  {
    /* probe UNIX support */
    struct sockaddr_un s_un;

    if (strlen (unixpath) >= sizeof (s_un.sun_path))
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
           _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
           (unsigned long long) sizeof (s_un.sun_path));
      unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
      LOG (GNUNET_ERROR_TYPE_INFO,
	   _("Using `%s' instead\n"),
           unixpath);
    }
#ifdef LINUX
    abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
                                                     "TESTING",
                                                     "USE_ABSTRACT_SOCKETS");
    if (GNUNET_SYSERR == abstract)
      abstract = GNUNET_NO;
#endif
    if ((GNUNET_YES != abstract)
        && (GNUNET_OK !=
            GNUNET_DISK_directory_create_for_file (unixpath)))
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
				"mkdir",
				unixpath);
  }
  if (NULL != unixpath)
  {
    desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
    if (NULL == desc)
    {
      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
          (EACCES == errno))
      {
        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
        GNUNET_free_non_null (hostname);
        GNUNET_free (unixpath);
        return GNUNET_SYSERR;
      }
      LOG (GNUNET_ERROR_TYPE_INFO,
           _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
           service_name,
           STRERROR (errno));
      GNUNET_free (unixpath);
      unixpath = NULL;
    }
    else
    {
      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
      desc = NULL;
    }
  }
#endif

  if ((0 == port) && (NULL == unixpath))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR,
         _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
         service_name);
    GNUNET_free_non_null (hostname);
    return GNUNET_SYSERR;
  }
  if (0 == port)
  {
    saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
    saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
    add_unixpath (saddrs, saddrlens, unixpath, abstract);
    GNUNET_free_non_null (unixpath);
    GNUNET_free_non_null (hostname);
    *addrs = saddrs;
    *addr_lens = saddrlens;
    return 1;
  }

  if (NULL != hostname)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Resolving `%s' since that is where `%s' will bind to.\n",
         hostname,
         service_name);
    memset (&hints, 0, sizeof (struct addrinfo));
    if (disablev6)
      hints.ai_family = AF_INET;
    hints.ai_protocol = IPPROTO_TCP;
    if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
        (NULL == res))
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Failed to resolve `%s': %s\n"),
           hostname,
           gai_strerror (ret));
      GNUNET_free (hostname);
      GNUNET_free_non_null (unixpath);
      return GNUNET_SYSERR;
    }
    next = res;
    i = 0;
    while (NULL != (pos = next))
    {
      next = pos->ai_next;
      if ((disablev6) && (pos->ai_family == AF_INET6))
        continue;
      i++;
    }
    if (0 == i)
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
           _("Failed to find %saddress for `%s'.\n"),
           disablev6 ? "IPv4 " : "",
           hostname);
      freeaddrinfo (res);
      GNUNET_free (hostname);
      GNUNET_free_non_null (unixpath);
      return GNUNET_SYSERR;
    }
    resi = i;
    if (NULL != unixpath)
      resi++;
    saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
    saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
    i = 0;
    if (NULL != unixpath)
    {
      add_unixpath (saddrs, saddrlens, unixpath, abstract);
      i++;
    }
    next = res;
    while (NULL != (pos = next))
    {
      next = pos->ai_next;
      if ((disablev6) && (AF_INET6 == pos->ai_family))
        continue;
      if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
        continue;               /* not TCP */
      if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
        continue;               /* huh? */
      LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
           service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
      if (AF_INET == pos->ai_family)
      {
        GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
        saddrlens[i] = pos->ai_addrlen;
        saddrs[i] = GNUNET_malloc (saddrlens[i]);
        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
        ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
      }
      else
      {
        GNUNET_assert (AF_INET6 == pos->ai_family);
        GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
        saddrlens[i] = pos->ai_addrlen;
        saddrs[i] = GNUNET_malloc (saddrlens[i]);
        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
        ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
      }
      i++;
    }
    GNUNET_free (hostname);
    freeaddrinfo (res);
    resi = i;
  }
  else
  {
    /* will bind against everything, just set port */
    if (disablev6)
    {
      /* V4-only */
      resi = 1;
      if (NULL != unixpath)
        resi++;
      i = 0;
      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
      if (NULL != unixpath)
      {
        add_unixpath (saddrs, saddrlens, unixpath, abstract);
        i++;
      }
      saddrlens[i] = sizeof (struct sockaddr_in);
      saddrs[i] = GNUNET_malloc (saddrlens[i]);
#if HAVE_SOCKADDR_IN_SIN_LEN
      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
#endif
      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
    }
    else
    {
      /* dual stack */
      resi = 2;
      if (NULL != unixpath)
        resi++;
      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
      i = 0;
      if (NULL != unixpath)
      {
        add_unixpath (saddrs, saddrlens, unixpath, abstract);
        i++;
      }
      saddrlens[i] = sizeof (struct sockaddr_in6);
      saddrs[i] = GNUNET_malloc (saddrlens[i]);
#if HAVE_SOCKADDR_IN_SIN_LEN
      ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
#endif
      ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
      ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
      i++;
      saddrlens[i] = sizeof (struct sockaddr_in);
      saddrs[i] = GNUNET_malloc (saddrlens[i]);
#if HAVE_SOCKADDR_IN_SIN_LEN
      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
#endif
      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
    }
  }
  GNUNET_free_non_null (unixpath);
  *addrs = saddrs;
  *addr_lens = saddrlens;
  return resi;
}
コード例 #14
0
ファイル: plugin_namecache_flat.c プロジェクト: tg-x/gnunet
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return #GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *afsdir;
  char* block_buffer;
  char* buffer;
  char* line;
  char* query;
  char* block;
  size_t size;
  struct FlatFileEntry *entry;
  struct GNUNET_DISK_FileHandle *fh;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namecache-flat",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                               "namecache-flat", "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
  }
  /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = afsdir;

  /* Load data from file into hashmap */
  plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
                                                     GNUNET_NO);
  fh = GNUNET_DISK_file_open (afsdir,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to initialize file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir,
                                              &size,
                                              GNUNET_YES,
                                              GNUNET_YES))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to get filesize: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  if (0 == size)
    return GNUNET_OK;

  buffer = GNUNET_malloc (size);

  if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh,
                                              buffer,
                                              size))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to read file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  GNUNET_DISK_file_close (fh);
  if (0 < size) {
    line = strtok (buffer, "\n");
    while (line != NULL) {
      query = strtok (line, ",");
      if (NULL == query)
        break;
      block = strtok (NULL, ",");
      if (NULL == block)
        break;
      line = strtok (NULL, "\n");
      entry = GNUNET_malloc (sizeof (struct FlatFileEntry));
      GNUNET_CRYPTO_hash_from_string (query,
                                      &entry->query);
      GNUNET_STRINGS_base64_decode (block,
                                    strlen (block),
                                    &block_buffer);
      entry->block = (struct GNUNET_GNSRECORD_Block *) block_buffer;
      if (GNUNET_OK != 
          GNUNET_CONTAINER_multihashmap_put (plugin->hm,
                                             &entry->query,
                                             entry,
                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
      {
        GNUNET_free (entry);
        GNUNET_break (0);
      }
    }
  }
  GNUNET_free (buffer);
  return GNUNET_OK;
}