LassiConnection* lassi_server_connect(LassiServer *ls, const char *a) { DBusError e; DBusConnection *c = NULL; LassiConnection *lc = NULL; dbus_error_init(&e); if (ls->n_connections >= CONNECTIONS_MAX) goto finish; if (!(c = dbus_connection_open_private(a, &e))) { g_warning("Failed to connect to client: %s", e.message); goto finish; } lc = connection_add(ls, c, TRUE); finish: if (c) dbus_connection_unref(c); dbus_error_free(&e); return lc; }
int wget_connect(struct wgetfile *finfo) { extern struct cfg global_cfg; const char *host, *port; if(finfo->proto == HTTP && global_cfg.http_proxy){ host = global_cfg.http_proxy; port = global_cfg.http_proxy_port; }else{ host = finfo->host_name; port = finfo->host_port; } finfo->sock = connection_fd(host, port); if(finfo->sock == -1){ finfo->sock = dial(host, port); if(finfo->sock == -1) return 1; /* dial() prints the error */ connection_add(finfo->sock, host, port); }else{ output_err(OUT_INFO, "Reusing connection to %s:%s", host, port); } return 0; }
/** Launch a new cpuworker. Return 0 if we're happy, -1 if we failed. */ static int spawn_cpuworker(void) { tor_socket_t *fdarray; tor_socket_t fd; connection_t *conn; int err; fdarray = tor_malloc(sizeof(tor_socket_t)*2); if ((err = tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fdarray)) < 0) { log_warn(LD_NET, "Couldn't construct socketpair for cpuworker: %s", tor_socket_strerror(-err)); tor_free(fdarray); return -1; } tor_assert(SOCKET_OK(fdarray[0])); tor_assert(SOCKET_OK(fdarray[1])); fd = fdarray[0]; if (spawn_func(cpuworker_main, (void*)fdarray) < 0) { tor_close_socket(fdarray[0]); tor_close_socket(fdarray[1]); tor_free(fdarray); return -1; } log_debug(LD_OR,"just spawned a cpu worker."); #ifndef TOR_IS_MULTITHREADED tor_close_socket(fdarray[1]); /* don't need the worker's side of the pipe */ tor_free(fdarray); #endif conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX); /* set up conn so it's got all the data we need to remember */ conn->s = fd; conn->address = tor_strdup("localhost"); tor_addr_make_unspec(&conn->addr); if (set_socket_nonblocking(fd) == -1) { connection_free(conn); /* this closes fd */ return -1; } if (connection_add(conn) < 0) { /* no space, forget it */ log_warn(LD_NET,"connection_add for cpuworker failed. Giving up."); connection_free(conn); /* this closes fd */ return -1; } conn->state = CPUWORKER_STATE_IDLE; connection_start_reading(conn); return 0; /* success */ }
static void new_connection(DBusServer *s, DBusConnection *c, void *userdata) { LassiServer *ls = userdata; g_assert(s); g_assert(c); if (ls->n_connections >= CONNECTIONS_MAX) return; dbus_connection_set_allow_anonymous(c, TRUE); connection_add(ls, c, FALSE); }
static void _expand(struct connection_server * server) { connection_deletepool(server->pool); server->pool = connection_newpool(server->max_connection * 2); int i; for (i=0;i<server->max_connection;i++) { struct connection * c = &server->conn[i]; int err = connection_add(server->pool, c->fd , c); assert(err == 0); } server->max_connection *= 2; }
void _modinit(module_t *m) { int kq; kq = kqueue(); if (kq == -1) { m->mflags = MODTYPE_FAIL; return; } kq_conn = connection_add("procwatch kqueue", kq, 0, procwatch_readhandler, NULL); service_named_bind_command("operserv", &os_procwatch); }
/** Helper function: called whenever the client sends a resolve request to our * controller. We need to eventually answer the request <b>req</b>. * Returns 0 if the controller will be getting (or has gotten) an event in * response; -1 if we couldn't launch the request. */ int dnsserv_launch_request(const char *name, int reverse) { entry_connection_t *entry_conn; edge_connection_t *conn; char *q_name; /* Make a new dummy AP connection, and attach the request to it. */ entry_conn = entry_connection_new(CONN_TYPE_AP, AF_INET); conn = ENTRY_TO_EDGE_CONN(entry_conn); conn->base_.state = AP_CONN_STATE_RESOLVE_WAIT; if (reverse) entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; else entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE; conn->is_dns_request = 1; strlcpy(entry_conn->socks_request->address, name, sizeof(entry_conn->socks_request->address)); entry_conn->socks_request->listener_type = CONN_TYPE_CONTROL_LISTENER; entry_conn->original_dest_address = tor_strdup(name); entry_conn->session_group = SESSION_GROUP_CONTROL_RESOLVE; entry_conn->nym_epoch = get_signewnym_epoch(); entry_conn->isolation_flags = ISO_DEFAULT; if (connection_add(TO_CONN(conn))<0) { log_warn(LD_APP, "Couldn't register dummy connection for RESOLVE request"); connection_free(TO_CONN(conn)); return -1; } /* Now, unless a controller asked us to leave streams unattached, * throw the connection over to get rewritten (which will * answer it immediately if it's in the cache, or completely bogus, or * automapped), and then attached to a circuit. */ log_info(LD_APP, "Passing request for %s to rewrite_and_attach.", escaped_safe_str_client(name)); q_name = tor_strdup(name); /* q could be freed in rewrite_and_attach */ connection_ap_rewrite_and_attach_if_allowed(entry_conn, NULL, NULL); /* Now, the connection is marked if it was bad. */ log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.", escaped_safe_str_client(q_name)); tor_free(q_name); return 0; }
static void _add(struct connection_server * server, int fd , uint32_t address) { ++server->current_connection; if (server->current_connection > server->max_connection) { _expand(server); } int i; for (i=0;i<server->max_connection;i++) { struct connection * c = &server->conn[i]; if (c->address == 0) { c->fd = fd; c->address = address; c->close = 0; int err = connection_add(server->pool, fd , c); assert(err == 0); return; } } assert(0); }
void setup_outgoing_connection(outgoing_t *outgoing) { connection_t *c; node_t *n; outgoing->event = NULL; n = lookup_node(outgoing->name); if(n) if(n->connection) { ifdebug(CONNECTIONS) logger(LOG_INFO, "Already connected to %s", outgoing->name); n->connection->outgoing = outgoing; return; } c = new_connection(); c->name = xstrdup(outgoing->name); c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; init_configuration(&c->config_tree); read_connection_config(c); outgoing->cfg = lookup_config(c->config_tree, "Address"); if(!outgoing->cfg) { logger(LOG_ERR, "No address specified for %s", c->name); free_connection(c); return; } c->outgoing = outgoing; c->last_ping_time = now; connection_add(c); do_outgoing_connection(c); }
/* accept a new tcp connect and create a new connection */ bool handle_new_meta_connection(int sock) { connection_t *c; sockaddr_t sa; int fd; socklen_t len = sizeof(sa); fd = accept(sock, &sa.sa, &len); if(fd < 0) { logger(LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); return false; } sockaddrunmap(&sa); c = new_connection(); c->name = xstrdup("<unknown>"); c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; c->address = sa; c->hostname = sockaddr2hostname(&sa); c->socket = fd; c->last_ping_time = now; ifdebug(CONNECTIONS) logger(LOG_NOTICE, "Connection from %s", c->hostname); configure_tcp(c); connection_add(c); c->allow_request = ID; send_id(c); return true; }
/** Helper function: called by evdns whenever the client sends a request to our * DNSPort. We need to eventually answer the request <b>req</b>. */ static void evdns_server_callback(struct evdns_server_request *req, void *data_) { const listener_connection_t *listener = data_; entry_connection_t *entry_conn; edge_connection_t *conn; int i = 0; struct evdns_server_question *q = NULL, *supported_q = NULL; struct sockaddr_storage addr; struct sockaddr *sa; int addrlen; tor_addr_t tor_addr; uint16_t port; int err = DNS_ERR_NONE; char *q_name; tor_assert(req); log_info(LD_APP, "Got a new DNS request!"); req->flags |= 0x80; /* set RA */ /* First, check whether the requesting address matches our SOCKSPolicy. */ if ((addrlen = evdns_server_request_get_requesting_addr(req, (struct sockaddr*)&addr, (socklen_t)sizeof(addr))) < 0) { log_warn(LD_APP, "Couldn't get requesting address."); evdns_server_request_respond(req, DNS_ERR_SERVERFAILED); return; } (void) addrlen; sa = (struct sockaddr*) &addr; if (tor_addr_from_sockaddr(&tor_addr, sa, &port)<0) { log_warn(LD_APP, "Requesting address wasn't recognized."); evdns_server_request_respond(req, DNS_ERR_SERVERFAILED); return; } if (!socks_policy_permits_address(&tor_addr)) { log_warn(LD_APP, "Rejecting DNS request from disallowed IP."); evdns_server_request_respond(req, DNS_ERR_REFUSED); return; } /* Now, let's find the first actual question of a type we can answer in this * DNS request. It makes us a little noncompliant to act like this; we * should fix that eventually if it turns out to make a difference for * anybody. */ if (req->nquestions == 0) { log_info(LD_APP, "No questions in DNS request; sending back nil reply."); evdns_server_request_respond(req, 0); return; } if (req->nquestions > 1) { log_info(LD_APP, "Got a DNS request with more than one question; I only " "handle one question at a time for now. Skipping the extras."); } for (i = 0; i < req->nquestions; ++i) { if (req->questions[i]->dns_question_class != EVDNS_CLASS_INET) continue; switch (req->questions[i]->type) { case EVDNS_TYPE_A: case EVDNS_TYPE_AAAA: case EVDNS_TYPE_PTR: /* We always pick the first one of these questions, if there is one. */ if (! supported_q) supported_q = req->questions[i]; break; default: break; } } if (supported_q) q = supported_q; if (!q) { log_info(LD_APP, "None of the questions we got were ones we're willing " "to support. Sending NOTIMPL."); evdns_server_request_respond(req, DNS_ERR_NOTIMPL); return; } /* Make sure the name isn't too long: This should be impossible, I think. */ if (err == DNS_ERR_NONE && strlen(q->name) > MAX_SOCKS_ADDR_LEN-1) err = DNS_ERR_FORMAT; if (err != DNS_ERR_NONE || !supported_q) { /* We got an error? There's no question we're willing to answer? Then * send back an answer immediately; we're done. */ evdns_server_request_respond(req, err); return; } /* Make a new dummy AP connection, and attach the request to it. */ entry_conn = entry_connection_new(CONN_TYPE_AP, AF_INET); conn = ENTRY_TO_EDGE_CONN(entry_conn); CONNECTION_AP_EXPECT_NONPENDING(entry_conn); TO_CONN(conn)->state = AP_CONN_STATE_RESOLVE_WAIT; conn->is_dns_request = 1; tor_addr_copy(&TO_CONN(conn)->addr, &tor_addr); TO_CONN(conn)->port = port; TO_CONN(conn)->address = tor_addr_to_str_dup(&tor_addr); if (q->type == EVDNS_TYPE_A || q->type == EVDNS_TYPE_AAAA || q->type == EVDNS_QTYPE_ALL) { entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE; } else { tor_assert(q->type == EVDNS_TYPE_PTR); entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; } /* This serves our DNS port so enable DNS request by default. */ entry_conn->entry_cfg.dns_request = 1; if (q->type == EVDNS_TYPE_A || q->type == EVDNS_QTYPE_ALL) { entry_conn->entry_cfg.ipv4_traffic = 1; entry_conn->entry_cfg.ipv6_traffic = 0; entry_conn->entry_cfg.prefer_ipv6 = 0; } else if (q->type == EVDNS_TYPE_AAAA) { entry_conn->entry_cfg.ipv4_traffic = 0; entry_conn->entry_cfg.ipv6_traffic = 1; entry_conn->entry_cfg.prefer_ipv6 = 1; } strlcpy(entry_conn->socks_request->address, q->name, sizeof(entry_conn->socks_request->address)); entry_conn->socks_request->listener_type = listener->base_.type; entry_conn->dns_server_request = req; entry_conn->entry_cfg.isolation_flags = listener->entry_cfg.isolation_flags; entry_conn->entry_cfg.session_group = listener->entry_cfg.session_group; entry_conn->nym_epoch = get_signewnym_epoch(); if (connection_add(ENTRY_TO_CONN(entry_conn)) < 0) { log_warn(LD_APP, "Couldn't register dummy connection for DNS request"); evdns_server_request_respond(req, DNS_ERR_SERVERFAILED); connection_free(ENTRY_TO_CONN(entry_conn)); return; } control_event_stream_status(entry_conn, STREAM_EVENT_NEW_RESOLVE, 0); /* Now, unless a controller asked us to leave streams unattached, * throw the connection over to get rewritten (which will * answer it immediately if it's in the cache, or completely bogus, or * automapped), and then attached to a circuit. */ log_info(LD_APP, "Passing request for %s to rewrite_and_attach.", escaped_safe_str_client(q->name)); q_name = tor_strdup(q->name); /* q could be freed in rewrite_and_attach */ connection_ap_rewrite_and_attach_if_allowed(entry_conn, NULL, NULL); /* Now, the connection is marked if it was bad. */ log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.", escaped_safe_str_client(q_name)); tor_free(q_name); }
/** Helper function: called whenever the client sends a resolve request to our * controller. We need to eventually answer the request <b>req</b>. * Returns 0 if the controller will be getting (or has gotten) an event in * response; -1 if we couldn't launch the request. */ int dnsserv_launch_request(const char *name, int reverse, control_connection_t *control_conn) { entry_connection_t *entry_conn; edge_connection_t *conn; char *q_name; /* Make a new dummy AP connection, and attach the request to it. */ entry_conn = entry_connection_new(CONN_TYPE_AP, AF_INET); conn = ENTRY_TO_EDGE_CONN(entry_conn); CONNECTION_AP_EXPECT_NONPENDING(entry_conn); conn->base_.state = AP_CONN_STATE_RESOLVE_WAIT; tor_addr_copy(&TO_CONN(conn)->addr, &control_conn->base_.addr); #ifdef AF_UNIX /* * The control connection can be AF_UNIX and if so tor_addr_to_str_dup will * unhelpfully say "<unknown address type>"; say "(Tor_internal)" * instead. */ if (control_conn->base_.socket_family == AF_UNIX) { TO_CONN(conn)->port = 0; TO_CONN(conn)->address = tor_strdup("(Tor_internal)"); } else { TO_CONN(conn)->port = control_conn->base_.port; TO_CONN(conn)->address = tor_addr_to_str_dup(&control_conn->base_.addr); } #else TO_CONN(conn)->port = control_conn->base_.port; TO_CONN(conn)->address = tor_addr_to_str_dup(&control_conn->base_.addr); #endif if (reverse) entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; else entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE; conn->is_dns_request = 1; strlcpy(entry_conn->socks_request->address, name, sizeof(entry_conn->socks_request->address)); entry_conn->socks_request->listener_type = CONN_TYPE_CONTROL_LISTENER; entry_conn->original_dest_address = tor_strdup(name); entry_conn->entry_cfg.session_group = SESSION_GROUP_CONTROL_RESOLVE; entry_conn->nym_epoch = get_signewnym_epoch(); entry_conn->entry_cfg.isolation_flags = ISO_DEFAULT; if (connection_add(TO_CONN(conn))<0) { log_warn(LD_APP, "Couldn't register dummy connection for RESOLVE request"); connection_free(TO_CONN(conn)); return -1; } control_event_stream_status(entry_conn, STREAM_EVENT_NEW_RESOLVE, 0); /* Now, unless a controller asked us to leave streams unattached, * throw the connection over to get rewritten (which will * answer it immediately if it's in the cache, or completely bogus, or * automapped), and then attached to a circuit. */ log_info(LD_APP, "Passing request for %s to rewrite_and_attach.", escaped_safe_str_client(name)); q_name = tor_strdup(name); /* q could be freed in rewrite_and_attach */ connection_ap_rewrite_and_attach_if_allowed(entry_conn, NULL, NULL); /* Now, the connection is marked if it was bad. */ log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.", escaped_safe_str_client(q_name)); tor_free(q_name); return 0; }
static void on_db_save(void *unused) { int stdout_pipes[2], stderr_pipes[2]; pid_t pid; int errno1; if (!command) return; if (update_command_proc.running) { slog(LG_ERROR, "ERROR: database update command is still running"); return; } if (pipe(stdout_pipes) == -1) { int err = errno; slog(LG_ERROR, "ERROR: Couldn't create pipe for database update command: %s", strerror(err)); return; } if (pipe(stderr_pipes) == -1) { int err = errno; slog(LG_ERROR, "ERROR: Couldn't create pipe for database update command: %s", strerror(err)); close(stdout_pipes[0]); close(stdout_pipes[1]); return; } pid = fork(); switch (pid) { case -1: errno1 = errno; slog(LG_ERROR, "Failed to fork for database update command: %s", strerror(errno1)); return; case 0: connection_close_all_fds(); close(stdout_pipes[0]); close(stderr_pipes[0]); dup2(stdout_pipes[1], 1); dup2(stderr_pipes[1], 2); close(stdout_pipes[1]); close(stderr_pipes[1]); execl("/bin/sh", "sh", "-c", command, NULL); write(2, "Failed to exec /bin/sh\n", 23); _exit(255); return; default: close(stdout_pipes[1]); close(stderr_pipes[1]); update_command_proc.out = connection_add("update_command_stdout", stdout_pipes[0], 0, recvq_put, NULL); update_command_proc.err = connection_add("update_command_stderr", stderr_pipes[0], 0, recvq_put, NULL); update_command_proc.out->recvq_handler = update_command_stdout_handler; update_command_proc.err->recvq_handler = update_command_stderr_handler; update_command_proc.pid = pid; update_command_proc.running = 1; childproc_add(pid, "db_update", update_command_finished, NULL); break; } }