static struct server * new_server(int fd, int method) { struct server *server; server = malloc(sizeof(struct server)); memset(server, 0, sizeof(struct server)); server->buf = malloc(BUF_SIZE); server->recv_ctx = malloc(sizeof(struct server_ctx)); server->send_ctx = malloc(sizeof(struct server_ctx)); server->recv_ctx->connected = 0; server->send_ctx->connected = 0; server->fd = fd; ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); server->recv_ctx->server = server; server->send_ctx->server = server; if (method) { server->e_ctx = malloc(sizeof(struct enc_ctx)); server->d_ctx = malloc(sizeof(struct enc_ctx)); enc_ctx_init(method, server->e_ctx, 1); enc_ctx_init(method, server->d_ctx, 0); } else { server->e_ctx = NULL; server->d_ctx = NULL; } cork_dllist_add(&connections, &server->entries); return server; }
static server_t * new_server(int fd, int method) { server_t *server; server = ss_malloc(sizeof(server_t)); server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); server->send_ctx = ss_malloc(sizeof(server_ctx_t)); server->buf = ss_malloc(sizeof(buffer_t)); server->fd = fd; server->recv_ctx->server = server; server->recv_ctx->connected = 0; server->send_ctx->server = server; server->send_ctx->connected = 0; server->hostname = NULL; server->hostname_len = 0; if (method) { server->e_ctx = ss_malloc(sizeof(enc_ctx_t)); server->d_ctx = ss_malloc(sizeof(enc_ctx_t)); enc_ctx_init(method, server->e_ctx, 1); enc_ctx_init(method, server->d_ctx, 0); } else { server->e_ctx = NULL; server->d_ctx = NULL; } ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); balloc(server->buf, BUF_SIZE); return server; }
struct server* new_server(int fd, struct listen_ctx *listener) { server_conn++; struct server *server; server = malloc(sizeof(struct server)); server->buf = malloc(BUF_SIZE); server->recv_ctx = malloc(sizeof(struct server_ctx)); server->send_ctx = malloc(sizeof(struct server_ctx)); server->fd = fd; ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); ev_timer_init(&server->send_ctx->watcher, server_resolve_cb, 0.2, 0.5); ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, listener->timeout, listener->timeout * 5); server->recv_ctx->server = server; server->recv_ctx->connected = 0; server->send_ctx->server = server; server->send_ctx->connected = 0; server->stage = 0; server->query = NULL; server->listen_ctx = listener; if (listener->method) { server->e_ctx = malloc(sizeof(struct enc_ctx)); server->d_ctx = malloc(sizeof(struct enc_ctx)); enc_ctx_init(listener->method, server->e_ctx, 1); enc_ctx_init(listener->method, server->d_ctx, 0); } else { server->e_ctx = NULL; server->d_ctx = NULL; } server->buf_len = 0; server->buf_idx = 0; server->remote = NULL; return server; }
struct server* new_server(int fd, int method) { struct server *server; server = malloc(sizeof(struct server)); server->buf = malloc(BUF_SIZE); server->recv_ctx = malloc(sizeof(struct server_ctx)); server->send_ctx = malloc(sizeof(struct server_ctx)); server->fd = fd; ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); server->recv_ctx->server = server; server->recv_ctx->connected = 0; server->send_ctx->server = server; server->send_ctx->connected = 0; server->stage = 0; if (method) { server->e_ctx = malloc(sizeof(struct enc_ctx)); server->d_ctx = malloc(sizeof(struct enc_ctx)); enc_ctx_init(method, server->e_ctx, 1); enc_ctx_init(method, server->d_ctx, 0); } else { server->e_ctx = NULL; server->d_ctx = NULL; } server->buf_len = 0; server->buf_idx = 0; return server; }
static void ss_client_init(redsocks_client *client) { ss_client *sclient = (void*)(client + 1); ss_instance * ss = (ss_instance *)(client->instance+1); client->state = ss_new; if (enc_ctx_init(&ss->info, &sclient->e_ctx, 1)) log_error(LOG_ERR, "Shadowsocks failed to initialize encryption context."); if (enc_ctx_init(&ss->info, &sclient->d_ctx, 0)) log_error(LOG_ERR, "Shadowsocks failed to initialize decryption context."); }
static void ss_forward_pkt(redudp_client *client, struct sockaddr * destaddr, void *data, size_t pktlen) { ss_client *ssclient = (void*)(client + 1); ss_instance * ss = (ss_instance *)(client->instance+1); struct sockaddr_in * relayaddr = &client->instance->config.relayaddr; struct msghdr msg; struct iovec io[1]; ssize_t outgoing; int rc; ss_header_ipv4 header; size_t len = 0; size_t fwdlen = 0; void * buff = client->instance->shared_buff; /* build and send header */ // TODO: Better implementation and IPv6 Support header.addr_type = ss_addrtype_ipv4; header.addr = ((struct sockaddr_in *)destaddr)->sin_addr.s_addr; header.port = ((struct sockaddr_in *)destaddr)->sin_port; if (enc_ctx_init(&ss->info, &ss->e_ctx, 1)) { redudp_log_error(client, LOG_ERR, "Shadowsocks UDP failed to initialize encryption context."); return; } rc = ss_encrypt(&ss->e_ctx, (char *)&header, sizeof(header), buff, &len); if (rc) { if (len + pktlen < MAX_UDP_PACKET_SIZE) rc = ss_encrypt(&ss->e_ctx, (char *)data, pktlen, buff+len, &fwdlen); else rc = 0; } enc_ctx_free(&ss->e_ctx); if (!rc) { redudp_log_error(client, LOG_DEBUG, "Can't encrypt packet, dropping it"); return; } fwdlen += len; memset(&msg, 0, sizeof(msg)); msg.msg_name = relayaddr; msg.msg_namelen = sizeof(*relayaddr); msg.msg_iov = io; msg.msg_iovlen = SIZEOF_ARRAY(io); io[0].iov_base = buff; io[0].iov_len = fwdlen; outgoing = sendmsg(event_get_fd(&ssclient->udprelay), &msg, 0); if (outgoing == -1) { redudp_log_errno(client, LOG_DEBUG, "sendmsg: Can't forward packet, dropping it"); return; } else if (outgoing != fwdlen) { redudp_log_error(client, LOG_DEBUG, "sendmsg: I was sending %zd bytes, but only %zd were sent.", fwdlen, outgoing); return; } }
JNIEXPORT void JNICALL Java_me_smartproxy_crypto_CryptoUtils_initEncryptor(JNIEnv *env, jclass thiz, jstring jpassword, jstring jmethod, jlong id) { enc_connection *connection = enc_ctx_map[id]; if(connection == NULL) { const char *password = env->GetStringUTFChars(jpassword, 0); const char *method = env->GetStringUTFChars(jmethod, 0); connection = (enc_connection *)ss_malloc(sizeof(struct enc_connection)); connection->text_e_ctx = (enc_ctx *)ss_malloc(sizeof(struct enc_ctx)); connection->text_d_ctx = (enc_ctx *)ss_malloc(sizeof(struct enc_ctx)); int enc_method = enc_init(password, method); enc_ctx_init(enc_method, connection->text_e_ctx, 1); enc_ctx_init(enc_method, connection->text_d_ctx, 0); enc_ctx_map[id] = connection; env->ReleaseStringUTFChars(jpassword, password); env->ReleaseStringUTFChars(jmethod, method); } }
static struct server * new_server(int fd, struct listen_ctx *listener) { if (verbose) { server_conn++; } struct server *server; server = malloc(sizeof(struct server)); memset(server, 0, sizeof(struct server)); server->buf = malloc(BUF_SIZE); server->recv_ctx = malloc(sizeof(struct server_ctx)); server->send_ctx = malloc(sizeof(struct server_ctx)); server->fd = fd; ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, min(MAX_CONNECT_TIMEOUT, listener->timeout), listener->timeout); server->recv_ctx->server = server; server->recv_ctx->connected = 0; server->send_ctx->server = server; server->send_ctx->connected = 0; server->stage = 0; server->query = NULL; server->listen_ctx = listener; if (listener->method) { server->e_ctx = malloc(sizeof(struct enc_ctx)); server->d_ctx = malloc(sizeof(struct enc_ctx)); enc_ctx_init(listener->method, server->e_ctx, 1); enc_ctx_init(listener->method, server->d_ctx, 0); } else { server->e_ctx = NULL; server->d_ctx = NULL; } server->buf_len = 0; server->buf_idx = 0; server->remote = NULL; server->chunk = (struct chunk *)malloc(sizeof(struct chunk)); memset(server->chunk, 0, sizeof(struct chunk)); cork_dllist_add(&connections, &server->entries); return server; }
static void ss_pkt_from_server(int fd, short what, void *_arg) { redudp_client *client = _arg; ss_client *ssclient = (void*)(client + 1); ss_instance * ss = (ss_instance *)(client->instance+1); ss_header_ipv4 * header; ssize_t pktlen; size_t fwdlen; struct sockaddr_in udprelayaddr; int rc; void * buff = client->instance->shared_buff; void * buff2 = ss->buff; assert(fd == event_get_fd(&ssclient->udprelay)); pktlen = red_recv_udp_pkt(fd, buff, MAX_UDP_PACKET_SIZE, &udprelayaddr, NULL); if (pktlen == -1) return; if (enc_ctx_init(&ss->info, &ss->d_ctx, 0)) { redudp_log_error(client, LOG_ERR, "Shadowsocks UDP failed to initialize decryption context."); return; } rc = ss_decrypt(&ss->d_ctx, buff, pktlen, buff2, &fwdlen); enc_ctx_free(&ss->d_ctx); if (!rc) { redudp_log_error(client, LOG_DEBUG, "Can't decrypt packet, dropping it"); return; } header = (ss_header_ipv4 *)buff2; // We do not verify src address, but at least, we need to ensure address type is correct. if (header->addr_type != ss_addrtype_ipv4) { redudp_log_error(client, LOG_DEBUG, "Got address type #%u instead of expected #%u (IPv4).", header->addr_type, ss_addrtype_ipv4); return; } struct sockaddr_in pktaddr = { .sin_family = AF_INET, .sin_addr = { header->addr }, .sin_port = header->port, }; if (fwdlen < sizeof(*header)) { redudp_log_error(client, LOG_DEBUG, "Packet too short."); return; } fwdlen -= sizeof(*header); redudp_fwd_pkt_to_sender(client, buff2 + sizeof(*header), fwdlen, &pktaddr); }