예제 #1
0
static int
fqd_http_message_url(http_parser *p, const char *at, size_t len) {
  struct http_req *req = p->data;
  req->url = malloc(len+1);
  strlcpy(req->url, at, len+1);
  req->qs = strchr(req->url, '?');
  if(req->qs) *(req->qs++) = '\0';

  if (req->qs != NULL) {
    char *trailing = req->qs;
    for (uint32_t i = 0; i < strlen(req->qs); i++) {
      if (req->qs[i] == '&') {
        req->qs[i] = '\0';
        store_kv(&req->query_params, trailing);
        req->qs[i] = '&';
        trailing = &req->qs[i+1];
      }
    }
    store_kv(&req->query_params, trailing);
  }

  fq_debug(FQ_DEBUG_HTTP, ".on_url -> '%s'\n", req->url);
  fq_debug(FQ_DEBUG_HTTP, ".on_url query_string -> '%s'\n", req->qs);
  return 0;
}
예제 #2
0
파일: fq_client.c 프로젝트: ipstatic/fq
static int
fq_client_connect_internal(fq_conn_s *conn_s) {
  int rv = -1;
  uint32_t cmd = htonl(FQ_PROTO_CMD_MODE);
  fq_client_disconnect_internal(conn_s);
  conn_s->cmd_fd = fq_socket_connect(conn_s);
  if(conn_s->cmd_fd < 0) goto shutdown;
  fq_debug(FQ_DEBUG_CONN, "connect(cmd_fd) -> %d\n", conn_s->cmd_fd);
  if(write(conn_s->cmd_fd, &cmd, sizeof(cmd)) != sizeof(cmd))
    goto shutdown;
  if((rv = fq_client_do_auth(conn_s)) < 0) {
    fq_debug(FQ_DEBUG_CONN, "fq_client_do_auth -> %d\n", rv);
    goto shutdown;
  }
  if(conn_s->auth_hook) {
    if(conn_s->sync_hooks) enqueue_auth_hook_req(conn_s, 0);
    else conn_s->auth_hook((fq_client)conn_s, 0);
  }
  return 0;

 shutdown:
  if(conn_s->cmd_fd >= 0) {
    int toclose = conn_s->cmd_fd;
    conn_s->cmd_fd = -1;
    fq_debug(FQ_DEBUG_CONN, "close(cmd_fd) (in auth)\n");
    close(toclose);
    if(conn_s->disconnect_hook) conn_s->disconnect_hook(conn_s);
  }
  if(conn_s->auth_hook) {
    if(conn_s->sync_hooks) enqueue_auth_hook_req(conn_s, rv);
    else conn_s->auth_hook((fq_client)conn_s, rv);
  }
  return -1;
}
예제 #3
0
파일: fqd_peer.c 프로젝트: ipstatic/fq
static void
fqd_peer_auth_hook(fq_client conn, int authed) {
  int i;
  fqd_peer_connection *peer;
  peer = fq_client_get_userdata(conn);
  fq_debug(FQ_DEBUG_PEER, "authed(%s:%d) -> %d\n",
           peer->host, peer->port, authed);
  if(authed || !peer) return;

  pthread_mutex_lock(&lock);
  peer->online_and_bound = true;
  for(i=0;i<peer->n_bindings;i++) {
    peer_binding_info *bi = peer->bindings[i];
    fq_bind_req *breq;
    breq = calloc(1, sizeof(*breq));
    memcpy(&breq->exchange, &bi->exchange, sizeof(bi->exchange));
    breq->flags = FQ_BIND_PEER | (bi->perm ? FQ_BIND_PERM : 0);
    breq->program = strdup(bi->prog);
    fq_client_bind(conn, breq);
    fq_debug(FQ_DEBUG_PEER, "bindreq(%s:%d) %.*s/%s\n",
             peer->host, peer->port, bi->exchange.len, bi->exchange.name,
             bi->prog);
  }
  pthread_mutex_unlock(&lock);
}
예제 #4
0
파일: fq_client.c 프로젝트: ipstatic/fq
static void *
fq_data_worker(void *u) {
  int backoff = 0;
  bool zero;
  fq_conn_s *conn_s = (fq_conn_s *)u;

  ck_pr_inc_uint(&conn_s->thrcnt);

  while(conn_s->stop == 0) {
    if(conn_s->data_ready) {
      if(fq_client_data_connect_internal(conn_s) == 0) {
        backoff = 0; /* we're good, restart our backoff */
      }
      fq_debug(FQ_DEBUG_IO, "[data] connected\n");
      fq_data_worker_loop(conn_s);
      fq_debug(FQ_DEBUG_IO, "[data] connection failed: %s\n", conn_s->error);
    }
    if(backoff) usleep(backoff + (4096 - (lrand48()%8192)));  /* +/- 4ms */
    else backoff = 16384;
    if(backoff < 1000000) backoff += (backoff >> 4);
  }
  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);
  }

  ck_pr_dec_uint_zero(&conn_s->thrcnt, &zero);
  if(zero) fq_conn_free(conn_s);
  return (void *)NULL;
}
예제 #5
0
파일: fq_client.c 프로젝트: ipstatic/fq
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;
}
예제 #6
0
static fqd_queue_impl_data queue_jlog_setup(fq_rk *qname, uint32_t *count) {
  char qpath[PATH_MAX];
  jlog_id chkpt;
  struct queue_jlog *d;

  d = calloc(1, sizeof(*d));
  d->auto_chkpt = true;
  fqd_config_construct_queue_path(qpath, sizeof(qpath), qname);
  d->qpath = strdup(qpath);
  d->writer = jlog_new(d->qpath);
  if(jlog_ctx_open_writer(d->writer) != 0) {
    jlog_ctx_close(d->writer);
    d->writer = jlog_new(d->qpath);
    if(jlog_ctx_init(d->writer) != 0) {
      fq_debug(FQ_DEBUG_IO, "jlog init: %s\n", jlog_ctx_err_string(d->writer));
      goto bail;
    }
    jlog_ctx_close(d->writer);
    d->writer = jlog_new(d->qpath);
    if(jlog_ctx_open_writer(d->writer) != 0) {
      fq_debug(FQ_DEBUG_IO, "jlog writer: %s\n", jlog_ctx_err_string(d->writer));
      goto bail;
    }
  }
  d->reader = jlog_new(d->qpath);
  if(jlog_get_checkpoint(d->reader, "fq", &chkpt) != 0) {
    if(jlog_ctx_add_subscriber(d->reader, "fq", JLOG_BEGIN) != 0) {
      fq_debug(FQ_DEBUG_IO, "jlog add sub: %s\n", jlog_ctx_err_string(d->reader));
      goto bail;
    }
  }
  if(jlog_ctx_open_reader(d->reader, "fq") != 0) {
    fq_debug(FQ_DEBUG_IO, "jlog: %s\n", jlog_ctx_err_string(d->reader));
    goto bail;
  }
  uuid_generate(d->uuid);
  write_sig(d);
  *count = 0;
  (void)qname;
  return d;

 bail:
  if(d->writer) jlog_ctx_close(d->writer);
  if(d->reader) jlog_ctx_close(d->reader);
  free(d->qpath);
  free(d);
  return NULL;
}
예제 #7
0
static int
fqd_http_message_header_value(http_parser *p, const char *at, size_t len) {
  struct http_req *req = p->data;
  ck_ht_entry_t entry;
  ck_ht_hash_t hv;
  char *val;
  if(!req->fldname) return -1;
  val = malloc(len+1);
  strlcpy(val, at, len+1);
  fq_debug(FQ_DEBUG_HTTP, ".on_header_value -> '%s'\n", val);

  ck_ht_hash(&hv, &req->headers, req->fldname, strlen(req->fldname));
  ck_ht_entry_set(&entry, hv, req->fldname, strlen(req->fldname), val);

  if(ck_ht_set_spmc(&req->headers, hv, &entry) && !ck_ht_entry_empty(&entry)) {
    char *key = ck_ht_entry_key(&entry);
    char *value = ck_ht_entry_value(&entry);
    if(key && key != req->fldname) free(key);
    if(value && value != val) free(value);
  }

  if(!strcmp(req->fldname, "expect") && !strcasecmp(val,"100-continue"))
    req->expect_continue = HTTP_EXPECT_CONTINUE;
  req->fldname = NULL;
  return 0;
}
예제 #8
0
파일: fqd_peer.c 프로젝트: ipstatic/fq
static void
fqd_peer_disconnect_hook(fq_client conn) {
  fqd_peer_connection *peer;
  peer = fq_client_get_userdata(conn);
  fq_debug(FQ_DEBUG_PEER, "disconnect from peer(%s:%d)\n",
           peer->host, peer->port);
  if(peer) peer->online_and_bound = false;
}
예제 #9
0
static int
fqd_http_message_status(http_parser *p, const char *at, size_t len) {
  struct http_req *req = p->data;
  req->status = malloc(len+1);
  strlcpy(req->status, at, len+1);
  fq_debug(FQ_DEBUG_HTTP, ".on_status -> '%s'\n", req->status);
  return 0;
}
예제 #10
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;
}
예제 #11
0
파일: fqd_peer.c 프로젝트: ipstatic/fq
static void
fqd_peer_start(fqd_peer_connection *peer) {
  fq_debug(FQ_DEBUG_PEER, "starting peer(%s:%d)\n", peer->host, peer->port);
  fq_client_init(&peer->client, fqd_config_get_nodeid(), peerlog);
  fq_client_set_userdata(peer->client, peer);
  fq_client_creds(peer->client, peer->host, peer->port,
                  peer->user, peer->pass);
  fq_client_hooks(peer->client, &fqd_peer_hooks);
  fq_client_connect(peer->client);
}
예제 #12
0
static int
fqd_http_message_header_field(http_parser *p, const char *at, size_t len) {
  char *cp;
  struct http_req *req = p->data;
  req->fldname = malloc(len+1);
  strlcpy(req->fldname, at, len+1);
  for(cp=req->fldname;*cp;cp++) *cp = tolower(*cp);
  fq_debug(FQ_DEBUG_HTTP, ".on_header_field -> '%s'\n", req->fldname);
  return 0;
}
예제 #13
0
파일: fqd_listener.c 프로젝트: ipstatic/fq
void
fqd_remote_client_deref(remote_client *r) {
  bool zero;
  ck_pr_dec_uint_zero(&r->refcnt, &zero);
  fq_debug(FQ_DEBUG_CONN, "deref client -> %u%s\n",
           r->refcnt, zero ? " dropping" : "");
  if(zero) {
    close(r->fd);
    free(r);
  }
}
예제 #14
0
파일: fq_msg.c 프로젝트: denji/fq
fq_msg *
fq_msg_alloc_BLANK(size_t s) {
  fq_msg *m;
  m = calloc(offsetof(fq_msg, payload) + ((s | (MSG_ALIGN-1))+1), 1);
  if(!m) return NULL;
  m->payload_len = s;
#ifdef DEBUG
    fq_debug(FQ_DEBUG_MSG, "msg(%p) -> alloc\n", (void *)m);
#endif
  m->refcnt = 1;
  return m;
}
예제 #15
0
파일: fq_msg.c 프로젝트: kaleidicforks/fq
void
fq_msg_deref(fq_msg *msg) {
  bool zero;

  ck_pr_dec_uint_zero(&msg->refcnt, &zero);
  if(zero) {
#ifdef DEBUG
    fq_debug(FQ_DEBUG_MSG, "msg(%p) -> free\n", (void *)msg);
#endif
    free(msg);
  }
}
예제 #16
0
파일: fq_utils.c 프로젝트: denji/fq
void
fq_debug_stacktrace(fq_debug_bits_t b, const char *tag, int start, int end) {
#define STACK_DEPTH 16
  int i, cnt;
  void *bti[STACK_DEPTH + 1], **bt = bti+1;
  char **btname;
  cnt = backtrace(bti, STACK_DEPTH + 1);
  if(cnt < 1) {
    fq_debug(b, "track trace failed\n");
    return;
  }
  btname = backtrace_symbols(bt, cnt);
  if(start > cnt) start = cnt;
  if(end > cnt) end = cnt;
  for(i=start;i!=end;i += (start > end) ? -1 : 1) {
    if(btname && btname[i])
      fq_debug(b, "[%2d] %s %s\n", i, tag, btname[i]);
    else
      fq_debug(b, "[%2d] %s %p\n", i, tag, bt[i]);
  }
  if(btname) free(btname);
}
예제 #17
0
파일: fqd_peer.c 프로젝트: ipstatic/fq
static void
fqd_peer_online_unbind(fqd_peer_connection *peer, peer_binding_info *bi) {
  fq_unbind_req *ureq;
  if(!bi->disabled || bi->disable_requested ||
     !peer->online_and_bound || bi->route_id == FQ_BIND_ILLEGAL) return;

  fq_debug(FQ_DEBUG_PEER, "unbinding peer(%s:%d) exchange:\"%.*s\"\n",
           peer->host, peer->port, bi->exchange.len, bi->exchange.name);
  ureq = calloc(1, sizeof(*ureq));
  memcpy(&ureq->exchange, &bi->exchange, sizeof(bi->exchange));
  ureq->route_id = bi->route_id;
  fq_client_unbind(peer->client, ureq);
}
예제 #18
0
파일: fqd_peer.c 프로젝트: ipstatic/fq
static void
fqd_peer_online_bind(fqd_peer_connection *peer, peer_binding_info *bi) {
  if(peer->online_and_bound == true) {
    fq_bind_req *breq;
    fq_debug(FQ_DEBUG_PEER, "binding peer(%s:%d) exchange:\"%.*s\"\n",
             peer->host, peer->port, bi->exchange.len, bi->exchange.name);
    breq = calloc(1, sizeof(*breq));
    memcpy(&breq->exchange, &bi->exchange, sizeof(bi->exchange));
    breq->flags = FQ_BIND_PEER | FQ_BIND_PERM;
    breq->program = strdup(bi->prog);
    fq_client_bind(peer->client, breq);
  }
}
예제 #19
0
파일: fqd_dss.c 프로젝트: ipstatic/fq
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");
}
예제 #20
0
static int
fqd_http_message_body(http_parser *p, const char *at, size_t len) {
  struct http_req *req = p->data;
  fq_debug(FQ_DEBUG_HTTP, ".on_data -> %zu\n", len);
  if(req->msg) {
    if(req->body_read + len > req->body_len) {
      req->error = strdup("excessive data received");
      return 1;
    }
    memcpy(req->msg->payload + req->body_read, at, len);
    req->body_read += len;
  }
  return 0;
}
예제 #21
0
파일: fq_msg.c 프로젝트: denji/fq
fq_msg *
fq_msg_alloc(const void *data, size_t s) {
  fq_msg *m;
  m = malloc(offsetof(fq_msg, payload) + ((s | (MSG_ALIGN-1))+1));
  if(!m) return NULL;
  m->payload_len = s;
  memset(m, 0, offsetof(fq_msg, payload));
  if(s) memcpy(m->payload, data, s);
#ifdef DEBUG
    fq_debug(FQ_DEBUG_MSG, "msg(%p) -> alloc\n", (void *)m);
#endif
  m->refcnt = 1;
  return m;
}
예제 #22
0
파일: fq_client.c 프로젝트: retailnext/fq
static void
fq_client_disconnect_internal(fq_conn_s *conn_s) {
  if(conn_s->cmd_fd >= 0) {
#ifdef DEBUG
    fq_debug(FQ_DEBUG_CONN, "close(cmd_fd)\n");
#endif
    close(conn_s->data_fd);
  }
  if(conn_s->data_fd >= 0) {
#ifdef DEBUG
    fq_debug(FQ_DEBUG_CONN, "close(data_fd)\n");
#endif
    close(conn_s->data_fd);
  }
  conn_s->data_ready = 0;
  if(conn_s->cmd_hb_ms) {
    unsigned short hb;
    hb = conn_s->cmd_hb_ms;
    conn_s->cmd_hb_ms = 0;
    fq_client_heartbeat(conn_s, hb);
    conn_s->cmd_hb_last = 0;
  }
}
예제 #23
0
static void queue_jlog_dispose(fq_rk *qname, fqd_queue_impl_data f) {
  struct queue_jlog *d = (struct queue_jlog *)f;
  uuid_t exist;
  (void)qname;
  uuid_clear(exist);
  read_sig(d, exist);
  if(uuid_compare(d->uuid, exist) == 0) {
    /* This is my jlog queue ... I can delete it */
    fq_debug(FQ_DEBUG_IO, "jlog: removing %s\n", d->qpath);
    nftw(d->qpath, multi_unlink, 2, FTW_DEPTH);
    rmdir(d->qpath);
  }
  free(d);
}
예제 #24
0
static int
fqd_http_reset_to_checkpoint(struct http_req *req)
{
  fqd_config *config = fqd_config_get();
  const char *cpname = get_ht_value(&req->query_params, "cpname");
  const char *qname = get_ht_value(&req->query_params, "qname");

  fq_rk qn;
  fq_rk_from_str(&qn, qname);

  fqd_queue *queue = fqd_config_get_registered_queue(config, &qn);

  if (strcmp(cpname, "fq") == 0) {
    fqd_http_error_json(req->client, "'fq' is a reserved name, cannot be used for a checkpoint name");
    req->close = 1;
    return 0;
  }

  if (queue == NULL) {
    fqd_http_error_json_f(req->client, "Cannot find registered queue '%s'", qname);
    req->close = 1;
    return 0;
  }

  int rv = queue->impl->reset_checkpoint(queue->impl_data, cpname);
  if (rv == -1) {
    fqd_http_error_json(req->client, "Checkpoint does not exist");
    req->close = 1;
    return 0;
  }

  if (rv < 0) {
    fqd_http_error_json(req->client, "Unknown error");
    req->close = 1;
    return 0;
  }

  fqd_http_success_json_f(req->client, "'%s' reset to checkpoint '%s'", qname, cpname);
  req->close = 1;
  fq_debug(FQ_DEBUG_HTTP, ".on_complete -> reset_to_checkpoint on [%s] for queue [%s]\n", cpname, qname);
  return 0;
}
예제 #25
0
파일: fqd_peer.c 프로젝트: ipstatic/fq
static bool
fqd_peer_message_hook(fq_client conn, fq_msg *m) {
  int i;
  uint32_t me = fqd_config_get_nodeid();
  fqd_peer_connection *peer;
  peer = fq_client_get_userdata(conn);
  for(i=MAX_HOPS-1;i>0;i--) {
    if(m->hops[i] == me) {
      fq_debug(FQ_DEBUG_PEER, "recieved looped message");
      return true;
    }
    m->hops[i] = m->hops[i-1];
  }
  m->hops[0] = fqd_config_get_nodeid();

  /* route this */
  fq_msg_ref(m);
  fqd_inject_message(peer ? peer->stats_holder : NULL, m);
  return true;
}
예제 #26
0
/* split incoming string by '=' and store the left as key and right as value in the table */
static void
store_kv(ck_ht_t *table, char *kv_string) {
  ck_ht_entry_t entry;
  ck_ht_hash_t hv;

  const char *key = kv_string;
  char *eq = strchr(kv_string, '=');
  if(eq) eq[0] = '\0';
  const char *val = eq ? eq + 1 : "";

  ck_ht_hash(&hv, table, key, strlen(key));
  ck_ht_entry_set(&entry, hv, strdup(key), strlen(key), strdup(val));

  if(ck_ht_set_spmc(table, hv, &entry)) {
    fq_debug(FQ_DEBUG_HTTP, ".store_kv -> added (%s, %s)\n", key, val);
  }

  /* be non-destructive */
  if(eq) eq[0] = '=';
}
예제 #27
0
static void queue_jlog_dispose(fq_rk *qname, fqd_queue_impl_data f)
{
  struct queue_jlog *d = (struct queue_jlog *)f;
  uuid_t exist;
  (void)qname;

  if (d == NULL) {
    /* there was likely a total failure to init this queue type
       due to file system permissions, bail
    */
    return;
  }

  uuid_clear(exist);
  read_sig(d, exist);
  if(uuid_compare(d->uuid, exist) == 0) {
    /* This is my jlog queue ... I can delete it */
    fq_debug(FQ_DEBUG_IO, "jlog: removing %s\n", d->qpath);
    nftw(d->qpath, multi_unlink, 2, FTW_DEPTH);
    rmdir(d->qpath);
  }
  free(d);
}
예제 #28
0
파일: fqd_peer.c 프로젝트: ipstatic/fq
static void
fqd_peer_bind_hook(fq_client conn, fq_bind_req *breq) {
  int i;
  fqd_peer_connection *peer;
  peer = fq_client_get_userdata(conn);
  if(!peer) return;
  fq_debug(FQ_DEBUG_PEER, "bindresp(%u) %.*s/%s\n",
           breq->out__route_id, breq->exchange.len, breq->exchange.name,
           breq->program);
  if(breq->out__route_id == FQ_BIND_ILLEGAL) {
    return;
  }
  pthread_mutex_lock(&lock);
  for(i=0;i<peer->n_bindings;i++) {
    peer_binding_info *bi = peer->bindings[i];
    if(!fq_rk_cmp(&bi->exchange, &breq->exchange) &&
       !strcmp(bi->prog, breq->program)) {
      bi->route_id = breq->out__route_id;
      break;
    }
  }
  pthread_mutex_unlock(&lock);
}
예제 #29
0
파일: fq_client.c 프로젝트: retailnext/fq
static void *
fq_data_worker(void *u) {
  int backoff = 0;
  fq_conn_s *conn_s = (fq_conn_s *)u;
  while(conn_s->stop == 0) {
    if(conn_s->data_ready) {
      if(fq_client_data_connect_internal(conn_s) == 0) {
        backoff = 0; /* we're good, restart our backoff */
      }

      fq_data_worker_loop(conn_s);
#ifdef DEBUG
      fq_debug(FQ_DEBUG_IO, "[data] connection failed: %s\n", conn_s->error);
#endif
    }
    if(backoff < 1000000) backoff += 10000;
    if(backoff) usleep(backoff);
  }
  if(conn_s->data_fd >= 0) {
    close(conn_s->data_fd);
    conn_s->data_fd = -1;
  }
  return (void *)NULL;
}
예제 #30
0
파일: fq_client.c 프로젝트: ipstatic/fq
static void
fq_client_disconnect_internal(fq_conn_s *conn_s) {
  if(conn_s->cmd_fd >= 0) {
    int toclose = conn_s->cmd_fd;
    conn_s->cmd_fd = -1;
    fq_stacktrace(FQ_DEBUG_CONN, "close(cmd_fd)\n",1,2);
    close(toclose);
    if(conn_s->disconnect_hook) conn_s->disconnect_hook(conn_s);
  }
  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_ready = 0;
  if(conn_s->cmd_hb_ms) {
    unsigned short hb;
    hb = conn_s->cmd_hb_ms;
    conn_s->cmd_hb_ms = 0;
    fq_client_heartbeat(conn_s, hb);
    conn_s->cmd_hb_last = 0;
  }
}