static void lt_request_cli(void *arg) { int ret; lthread_t *lt = NULL; proxy_conn_t *priv_conn = proxy_conn_create(-1, 1); proxy_conn_t *proxy_conn = (proxy_conn_t*)arg; DEFINE_LTHREAD; lthread_detach(); fprintf(stderr, "request new client\n"); ret = tcp_dial_ipv4(&priv_conn->conn, "192.168.6.1:80"); if(0 != ret) { proxy_conn_free(priv_conn); proxy_conn_free(proxy_conn); return; } fprintf(stderr, "dial priv conn ok\n"); priv_conn->other = proxy_conn; proxy_conn->other = priv_conn; //lthread_create(<1, (void*)lt_proxy_loop, (void*)priv_conn); lthread_create(<, (void*)lt_proxy_loop, (void*)proxy_conn); lt_proxy_loop(priv_conn); lthread_join(lt, NULL, LTHREAD_FOREVER); void* data = NULL; kstring_t *buf = NULL; while(0 == chan_recv(priv_conn->write_ch, &data)) { if(data != NULL) { buf = (kstring_t*)data; ks_free(buf); free(buf); } else { //mark as end break; } } while(0 == chan_recv(proxy_conn->write_ch, &data)) { if(data != NULL) { buf = (kstring_t*)data; ks_free(buf); free(buf); } else { //mark as end break; } } proxy_conn_free(priv_conn); proxy_conn_free(proxy_conn); }
void lt_main(void *arg) { int fd, opt = 1; proxy_server *srv = (proxy_server*)arg; lthread_t *lt_accept = NULL; struct sockaddr cin = {0}; socklen_t addrlen = sizeof(struct sockaddr); proxy_conn_t *proxy = NULL; DEFINE_LTHREAD; lthread_detach(); srv->listen_fd = create_listener("0.0.0.0", 9000); if(srv->listen_fd < 0) { exit(1); } fprintf(stderr, "listener creating :9000\n"); lthread_create(<_accept, (void*)lt_accept_loop, (void*)srv); while(!srv->is_die) { fd = lthread_accept(srv->listen_fd, &cin, &addrlen); if(fd < 0) { perror("accept error"); break; } if(srv->quiting) { lthread_close(fd); break; } if(srv->is_die) { //already die, close and break lthread_close(fd); fprintf(stderr, "server already die :9000\n"); break; } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == -1) { perror("failed to set SOREUSEADDR on socket"); break; } fprintf(stderr, "accept new client\n"); proxy = proxy_conn_create(fd, 0); if(0 != chan_send(srv->accepts_ch, proxy)) { //send failed, free proxy proxy_conn_free(proxy); break; } //yield myself lthread_sleep((uint64_t)0); } if(-1 != srv->listen_fd) { close(srv->listen_fd); srv->listen_fd = -1; } if(!srv->is_die) { srv->is_die = 1; chan_close(srv->die_ch); fprintf(stderr, "srv die\n"); } fprintf(stderr, "lt_accept end\n"); lthread_join(lt_accept, NULL, LTHREAD_FOREVER); //server release server_release(srv); }
static int forward_cmd_parse_dst(pool *p, const char *arg, char **name, struct proxy_conn **pconn) { const char *default_proto = NULL, *default_port = NULL, *proto = NULL, *port, *uri = NULL; char *host = NULL, *hostport = NULL, *host_ptr = NULL, *port_ptr = NULL; /* TODO: Revisit theses default once we start supporting other protocols. */ default_proto = "ftp"; default_port = "21"; /* First, look for the optional port. */ port_ptr = strrchr(arg, ':'); if (port_ptr == NULL) { port = default_port; } else { char *tmp2 = NULL; long num; num = strtol(port_ptr+1, &tmp2, 10); if (tmp2 && *tmp2) { /* Trailing garbage found in port number. */ (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION, "malformed port number '%s' found in USER '%s', rejecting", port_ptr+1, arg); errno = EINVAL; return -1; } if (num < 0 || num > 65535) { (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION, "invalid port number %ld found in USER '%s', rejecting", num, arg); errno = EINVAL; return -1; } port = pstrdup(p, port_ptr + 1); } /* Find the required '@' delimiter. */ host_ptr = strrchr(arg, '@'); if (host_ptr == NULL) { (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION, "missing required '@' delimiter in USER '%s', rejecting", arg); errno = EINVAL; return -1; } if (port_ptr == NULL) { host = pstrdup(p, host_ptr + 1); } else { host = pstrndup(p, host_ptr + 1, (port_ptr - host_ptr - 1)); } *name = pstrndup(p, arg, (host_ptr - arg)); proto = default_proto; hostport = pstrcat(p, host, ":", port, NULL); if (forward_dst_filter(p, hostport) < 0) { return -1; } uri = pstrcat(p, proto, "://", hostport, NULL); /* Note: We deliberately use proxy_pool, rather than the given pool, here * so that the created structure (especially the pr_netaddr_t) are * longer-lived. */ *pconn = proxy_conn_create(proxy_pool, uri); if (*pconn == NULL) { int xerrno = errno; pr_trace_msg(trace_channel, 1, "error handling URI '%.100s': %s", uri, strerror(xerrno)); errno = xerrno; return -1; } return 0; }