Beispiel #1
0
static int
fq_client_do_auth(fq_conn_s *conn_s) {
  int len, qlen, qtlen;
  uint16_t cmd;
  char error[1024];
  char queue_composed[MAX_RK_LEN*2 + 1];
  if(fq_write_uint16(conn_s->cmd_fd, FQ_PROTO_AUTH_CMD)) return -1;
  if(fq_write_uint16(conn_s->cmd_fd, FQ_PROTO_AUTH_PLAIN)) return -2;
  if(fq_write_short_cmd(conn_s->cmd_fd, strlen(conn_s->user), conn_s->user) < 0)
    return -3;

  qlen = strlen(conn_s->queue);
  if(qlen > MAX_RK_LEN) qlen = MAX_RK_LEN;
  qtlen = strlen(conn_s->queue_type);
  if(qtlen > MAX_RK_LEN) qtlen = MAX_RK_LEN;
  len = qlen + qtlen + 1;
  memcpy(queue_composed, conn_s->queue, qlen);
  queue_composed[qlen] = '\0';
  memcpy(queue_composed + qlen + 1, conn_s->queue_type, qtlen);
  if(fq_write_short_cmd(conn_s->cmd_fd, len, queue_composed) < 0)
    return -4;
  if(fq_write_short_cmd(conn_s->cmd_fd, strlen(conn_s->pass), conn_s->pass) < 0)
    return -5;
  if(fq_read_uint16(conn_s->cmd_fd, &cmd)) return -6;
  switch(cmd) {
    case FQ_PROTO_ERROR:
      len = fq_read_short_cmd(conn_s->cmd_fd, sizeof(error)-1, error);
      if(conn_s->errorlog) {
        if(len > (int)sizeof(error)-1) len = sizeof(error)-1;
        if(len < 0) conn_s->errorlog(conn_s, "error reading error");
        else conn_s->errorlog(conn_s,error);
      }
      return -7;
    case FQ_PROTO_AUTH_RESP:
      len = fq_read_short_cmd(conn_s->cmd_fd,
                              sizeof(conn_s->key.name), conn_s->key.name);
      if(len < 0 || len > (int)sizeof(conn_s->key.name)) return -8;
      conn_s->key.len = len;
#ifdef DEBUG
      {
        char hex[260];
        if(fq_rk_to_hex(hex, sizeof(hex), &conn_s->key) >= 0)
          fq_debug(FQ_DEBUG_CONN, "client keyed:\n%s\n", hex);
      }
#endif
      conn_s->data_ready = 1;
      break;
    default:
      if(conn_s->errorlog) {
        snprintf(error, sizeof(error),
                 "server auth response 0x%04x unknown\n", cmd);
        conn_s->errorlog(conn_s, error);
      }
      return -9;
  }
  return 0;
}
Beispiel #2
0
static int
fq_client_data_connect_internal(fq_conn_s *conn_s) {
  int flags;
  uint32_t cmd = htonl(conn_s->peermode ? FQ_PROTO_PEER_MODE
                                        : FQ_PROTO_DATA_MODE);
  /* We don't support data connections when the cmd connection is down */
  if(conn_s->cmd_fd < 0) return -1;

  if(conn_s->data_fd >= 0) {
    int toclose = conn_s->data_fd;
    conn_s->data_fd = -1;
    fq_debug(FQ_DEBUG_CONN, "close(data_fd)\n");
    close(toclose);
  }
  conn_s->data_fd = fq_socket_connect(conn_s);
  if(conn_s->data_fd < 0) goto shutdown;
  fq_debug(FQ_DEBUG_CONN, "connect(data_fd) -> %d\n", conn_s->data_fd);
  if(write(conn_s->data_fd, &cmd, sizeof(cmd)) != sizeof(cmd))
    goto shutdown;
  if(conn_s->peermode) {
    if(write(conn_s->data_fd, &conn_s->peermode,
             sizeof(conn_s->peermode)) != sizeof(conn_s->peermode))
      goto shutdown;
  }
#ifdef DEBUG
      {
        char hex[260];
        if(fq_rk_to_hex(hex, sizeof(hex), &conn_s->key) >= 0)
          fq_debug(FQ_DEBUG_CONN, "client keying:\n%s\n", hex);
      }
#endif
  if(fq_write_short_cmd(conn_s->data_fd,
                        conn_s->key.len, conn_s->key.name) < 0) {
    goto shutdown;
  }
  conn_s->tosend_offset = 0;
  if(((flags = fcntl(conn_s->data_fd, F_GETFL, 0)) == -1) ||
     (fcntl(conn_s->data_fd, F_SETFL, flags | O_NONBLOCK) == -1))
    goto shutdown;

  return 0;

 shutdown:
  if(conn_s->data_fd >= 0) {
    int toclose = conn_s->data_fd;
    conn_s->data_fd = -1;
    fq_debug(FQ_DEBUG_CONN, "close(data_fd)\n");
    close(toclose);
  }
  return -1;
}
Beispiel #3
0
extern void
fqd_data_subscription_server(remote_data_client *client) {
  int len;
  char buf[260];
  fqd_config *config;
  remote_client *parent;
  fq_rk key;
  fq_debug(FQ_DEBUG_CONN, "--> dss thread [%s]\n",
           client->mode == FQ_PROTO_DATA_MODE ? "client" : "peer");
  if((len = fq_read_short_cmd(client->fd, sizeof(key.name), key.name)) < 0)
    return;
  if(len > (int)sizeof(key.name)) return;
  key.len = len;

  fq_rk_to_hex(buf, sizeof(buf), &key);
  fq_debug(FQ_DEBUG_CONN, "data conn w/ key:\n%s\n", buf);

  config = fqd_config_get();
  parent = fqd_config_get_registered_client(config, &key);
  fqd_config_release(config);
  if(!parent) return;
  if(parent->data) return;
  ck_pr_cas_ptr(&parent->data, NULL, client);
  if(parent->data != client) {
    fq_debug(FQ_DEBUG_CONN, "%s dss double gang rejected\n", parent->pretty);
    return;
  }
  if(FQ_CLIENT_AUTH_DATA_ENABLED()) {
    fq_dtrace_remote_data_client_t dclient;
    DTRACE_PACK_DATA_CLIENT(&dclient, client);
    FQ_CLIENT_AUTH_DATA(&dclient);
  }
  fqd_remote_client_ref(parent);
  fqd_data_driver(parent);
  fq_clear_message_cleanup_stack();
  fqd_remote_client_deref(parent);
  fq_debug(FQ_DEBUG_CONN, "<-- dss thread\n");
}