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; }
int fq_read_status(int fd, void (*f)(char *, uint32_t, void *), void *closure) { while(1) { char key[0x10000]; int len; uint32_t value; len = fq_read_short_cmd(fd, 0xffff, key); if(len < 0) return -1; if(len == 0) break; key[len] = '\0'; if(fq_read_uint32(fd, &value) < 0) return -1; f(key, value, closure); } return 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"); }