Beispiel #1
0
struct argos_net_conn *
argos_net_client_create(struct sockaddr_in *remote_addr, int dlt,
    const struct sockaddr_in *client_ip, size_t inbufsz, size_t outbufsz,
    size_t pktbufsz)
{
    if (dlt < 0) {
        errno = EINVAL;
        return NULL;
    }

    /* inbufsz has to at least be big enough to hold a handshake message */
    if (inbufsz < sizeof(struct argos_net_handshake_msg)) {
        errno = ENOSPC;
        return NULL;
    }

    struct argos_net_conn *conn = malloc(sizeof(struct argos_net_conn));
    if (conn == NULL) return NULL;
    bzero(conn, sizeof(struct argos_net_conn));

    conn->dlt = dlt;
    conn->state = ARGOS_NET_CONN_IDLE;
    memcpy(&conn->remote_addr, remote_addr, sizeof(struct sockaddr_in));
    conn->init_backoff = ARGOS_NET_DEF_INIT_BACKOFF;
    conn->max_backoff = ARGOS_NET_DEF_MAX_BACKOFF;
    conn->cur_backoff = conn->init_backoff;
    conn->inbuf = buffer_create(inbufsz);
    if (conn->inbuf == NULL) goto fail;
    conn->outbuf = buffer_create(outbufsz);
    if (conn->outbuf == NULL) goto fail;
    conn->pktbuf = buffer_create(pktbufsz);
    if (conn->pktbuf == NULL) goto fail;

    /* outbuf and pktbuf should be empty! */
    assert(buffer_len(conn->outbuf) == 0);
    assert(buffer_len(conn->pktbuf) == 0);

    conn->handshake.msgtype = htons(ARGOS_NET_HANDSHAKE_MSGTYPE);
    conn->handshake.msglen = htonl(sizeof(struct argos_net_handshake_msg));
    conn->handshake.magicnum = htonl(ARGOS_NET_MAGICNUM);
    conn->handshake.major_version = htons(ARGOS_MAJOR_VERSION);
    conn->handshake.minor_version = htons(ARGOS_MINOR_VERSION);
    conn->handshake.dlt = htonl(conn->dlt);
    if (client_ip != NULL)
        conn->handshake.ip = client_ip->sin_addr.s_addr;

    /* start trying to connect */
    attempt_connect(conn);

    return conn;

 fail:
    if (conn->inbuf != NULL) buffer_destroy(conn->inbuf);
    if (conn->outbuf != NULL) buffer_destroy(conn->outbuf);
    if (conn->pktbuf != NULL) buffer_destroy(conn->pktbuf);
    free(conn);
    return NULL;
}
Beispiel #2
0
/**
 * PEERINFO calls this function to let us know about a possible peer
 * that we might want to connect to.
 *
 * @param cls closure (not used)
 * @param peer potential peer to connect to
 * @param hello HELLO for this peer (or NULL)
 * @param err_msg NULL if successful, otherwise contains error message
 */
static void
process_peer (void *cls,
              const struct GNUNET_PeerIdentity *peer,
              const struct GNUNET_HELLO_Message *hello,
              const char *err_msg)
{
  struct Peer *pos;

  if (NULL != err_msg)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                _("Error in communication with PEERINFO service: %s\n"),
                err_msg);
    GNUNET_PEERINFO_notify_cancel (peerinfo_notify);
    peerinfo_notify = GNUNET_PEERINFO_notify (cfg,
                                              GNUNET_NO,
                                              &process_peer,
                                              NULL);
    return;
  }
  GNUNET_assert (NULL != peer);
  if (0 == memcmp (&my_identity,
                   peer,
                   sizeof (struct GNUNET_PeerIdentity)))
    return;                     /* that's me! */
  if (NULL == hello)
  {
    /* free existing HELLO, if any */
    pos = GNUNET_CONTAINER_multipeermap_get (peers,
                                             peer);
    if (NULL != pos)
    {
      GNUNET_free_non_null (pos->hello);
      pos->hello = NULL;
      if (NULL != pos->filter)
      {
        GNUNET_CONTAINER_bloomfilter_free (pos->filter);
        pos->filter = NULL;
      }
      if ( (NULL == pos->mq) &&
           (GNUNET_NO == pos->is_friend) )
        free_peer (NULL,
                   &pos->pid,
                   pos);
    }
    return;
  }
  consider_for_advertising (hello);
  pos = GNUNET_CONTAINER_multipeermap_get (peers,
                                           peer);
  if (NULL == pos)
    pos = make_peer (peer,
                     hello,
                     GNUNET_NO);
  attempt_connect (pos);
}
Beispiel #3
0
static void
reconnect_event(void *arg)
{
    struct argos_net_conn *conn = arg;
    assert(conn->state == ARGOS_NET_CONN_BACKOFF);
    conn->state = ARGOS_NET_CONN_IDLE;
    conn->reconnect_evt_reg = NULL;

    (void) attempt_connect(conn);
}
Beispiel #4
0
/**
 * Try to add more peers to our connection set.
 *
 * @param cls closure, not used
 * @param pid identity of a peer
 * @param value `struct Peer *` for the peer
 * @return #GNUNET_YES (continue to iterate)
 */
static int
try_add_peers (void *cls,
               const struct GNUNET_PeerIdentity *pid,
               void *value)
{
  struct Peer *pos = value;

  attempt_connect (pos);
  return GNUNET_YES;
}
/**
 * Try to connect to the specified peer.
 *
 * @param cls peer to connect to
 * @param tc scheduler context
 */
static void
do_attempt_connect (void *cls,
		    const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct Peer *pos = cls;
  struct GNUNET_TIME_Relative delay;

  pos->attempt_connect_task = GNUNET_SCHEDULER_NO_TASK;
  if (GNUNET_YES == pos->is_connected)
    return;
  delay = GNUNET_TIME_absolute_get_remaining (next_connect_attempt);
  if (delay.rel_value > 0)
  {
    pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (delay,
							      &do_attempt_connect,
							      pos);
    return;
  }
  next_connect_attempt = GNUNET_TIME_relative_to_absolute (MAX_CONNECT_FREQUENCY_DELAY);
  attempt_connect (pos);
}