value unix_sendto_native(value sock, value buff, value ofs, value len, value flags, value dest) { SOCKET s = Socket_val(sock); int flg = convert_flag_list(flags, msg_flag_table); int ret; intnat numbytes; char iobuf[UNIX_BUFFER_SIZE]; union sock_addr_union addr; socklen_param_type addr_len; DWORD err = 0; get_sockaddr(dest, &addr, &addr_len); numbytes = Long_val(len); if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; memmove (iobuf, &Byte(buff, Long_val(ofs)), numbytes); enter_blocking_section(); ret = sendto(s, iobuf, (int) numbytes, flg, &addr.s_gen, addr_len); if (ret == -1) err = WSAGetLastError(); leave_blocking_section(); if (ret == -1) { win32_maperr(err); uerror("sendto", Nothing); } return Val_int(ret); }
void udphandler::sendto(const void *msg, int len, std::string host, int port) { sockaddr_storage saddr; if (! get_sockaddr(&saddr, host, port)) return; #ifndef WIN32 ssize_t sendlen = 0; size_t l = len; #else int sendlen = 0; int l = len; #endif // WIN32 if (m_domain == PF_INET) { sendlen = ::sendto(m_socket, msg, l, 0, (sockaddr*)&saddr, sizeof(sockaddr_in)); } else if (m_domain == PF_INET6) { sendlen = ::sendto(m_socket, msg, l, 0, (sockaddr*)&saddr, sizeof(sockaddr_in6)); } #ifndef WIN32 if (sendlen < 0) { perror("sendto"); } #else if (sendlen == SOCKET_ERROR) { perror("sendto"); } #endif // WIN32 }
/* * Connect to the given port on the given host, returning the connected * socket. If there are any errors, print an error message and exit. */ int tcp_connect(char *hostname, int port) { int skt; struct sockaddr_in *my_addr; my_addr = malloc(sizeof(struct sockaddr_in)); // create socket skt = socket(AF_INET, SOCK_STREAM, 0); if(skt<0){ die0("socket error\n"); } // set up sockaddr_in to be local settings (ie. settings on the client computer) memset((char *)my_addr, 0, sizeof(*my_addr)); my_addr->sin_family = AF_INET; my_addr->sin_port = htons(0); my_addr->sin_addr.s_addr = htonl(INADDR_ANY); bzero(&(my_addr->sin_zero),8); // first bind to LOCAL port printf("Binding to local port...\n"); if(bind(skt, (struct sockaddr *)my_addr, sizeof(struct sockaddr))<0) die0("bind error\n"); // set up to connect to REMOTE PORT my_addr = get_sockaddr(hostname, port, (struct sockaddr *)my_addr); printf("Connecting to port %d...\n", port); if(connect(skt, (struct sockaddr *)my_addr, sizeof(struct sockaddr))<0) die0("connect error\n"); printf("connected successfully to %s\n", hostname); return skt; }
CAMLprim value unix_getnameinfo(value vaddr, value vopts) { CAMLparam0(); CAMLlocal3(vhost, vserv, vres); union sock_addr_union addr; socklen_param_type addr_len; char host[4096]; char serv[1024]; int opts, retcode; get_sockaddr(vaddr, &addr, &addr_len); opts = convert_flag_list(vopts, getnameinfo_flag_table); enter_blocking_section(); retcode = getnameinfo((const struct sockaddr *) &addr.s_gen, addr_len, host, sizeof(host), serv, sizeof(serv), opts); leave_blocking_section(); if (retcode != 0) raise_not_found(); /* TODO: detailed error reporting? */ vhost = copy_string(host); vserv = copy_string(serv); vres = alloc_small(2, 0); Field(vres, 0) = vhost; Field(vres, 1) = vserv; CAMLreturn(vres); }
int cliser_client(lua_State *L) { #ifdef USE_CUDA // sometimes cutorch is loaded late, this is a good spot to try and register... Lcliser_CudaInit(L); #endif const char *host; const char *port; if (lua_type(L, 1) == LUA_TSTRING) { host = lua_tostring(L, 1); port = lua_tostring(L, 2); } else { host = DEFAULT_HOST; port = lua_tostring(L, 1); } socklen_t addrlen = sizeof(struct sockaddr); struct sockaddr addr; int ret = get_sockaddr(L, host, port, &addr, &addrlen); if (ret) return ret; struct timeval tv; gettimeofday(&tv, NULL); uint32_t t = tv.tv_sec + DEFAULT_TIMEOUT_SECONDS; int sock = -1; while (tv.tv_sec < t) { ret = socket(PF_INET, SOCK_STREAM, 0); if (ret <= 0) return LUA_HANDLE_ERROR(L, errno); sock = ret; int value = 1; ret = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); if (ret) break; ret = connect(sock, &addr, addrlen); if (!ret) break; close(sock); sleep(1); gettimeofday(&tv, NULL); } if (ret) { close(sock); return LUA_HANDLE_ERROR(L, errno); } addrlen = sizeof(struct sockaddr); struct sockaddr bind_addr; ret = getsockname(sock, &bind_addr, &addrlen); if (ret) { close(sock); return LUA_HANDLE_ERROR(L, errno); } int use_fastpath = can_use_fastpath(L, sock, ((struct sockaddr_in *)&bind_addr)->sin_addr.s_addr, ((struct sockaddr_in *)&addr)->sin_addr.s_addr); client_t *client = (client_t *)calloc(1, sizeof(client_t)); client->sock = sock; client->send_rb = ringbuffer_create(SEND_RECV_SIZE); client->recv_rb = ringbuffer_create(SEND_RECV_SIZE); client->ref_count = 1; client->copy_context.use_fastpath = use_fastpath; client_t **clientp = (client_t **)lua_newuserdata(L, sizeof(client_t *)); *clientp = client; luaL_getmetatable(L, "ipc.client"); lua_setmetatable(L, -2); return 1; }
//============================================================================= int SocketAddress::socket_bind(SOCKET s) const { return ::bind( s, get_sockaddr(), get_sockaddr_size() ); }
bool id_table::set_family(uint16_t id, uint8_t family) { struct sockaddr_storage* ss = get_sockaddr(id); if (ss == NULL) { return false; } ss->ss_family = family; return true; }
bool id_table::set_sockaddr(uint16_t id, struct sockaddr* sa, size_t salen) { struct sockaddr_storage* ss = get_sockaddr(id); if (ss == NULL) { return false; } else { memcpy(ss, sa, salen); return true; } }
CAMLprim value stub_utp_process_udp (value context, value addr, value buf, value off, value len) { CAMLparam5 (context, addr, buf, off, len); union sock_addr_union sock_addr; socklen_param_type addr_len; int handled; get_sockaddr (addr, &sock_addr, &addr_len); handled = utp_process_udp (Utp_context_val (context), Caml_ba_data_val (buf) + Int_val (off), Int_val (len), &sock_addr.s_gen, addr_len); CAMLreturn (Val_bool (handled)); }
CAMLprim value unix_bind(value socket, value address) { int ret; union sock_addr_union addr; socklen_param_type addr_len; get_sockaddr(address, &addr, &addr_len); ret = bind(Int_val(socket), &addr.s_gen, addr_len); if (ret == -1) uerror("bind", Nothing); return Val_unit; }
CAMLprim value stub_utp_connect (value sock, value addr) { CAMLparam2 (sock, addr); union sock_addr_union sock_addr; socklen_param_type addr_len; int res; get_sockaddr (addr, &sock_addr, &addr_len); res = utp_connect (Utp_socket_val (sock), &sock_addr.s_gen, addr_len); if (res < 0) caml_failwith ("utp_connect"); CAMLreturn (Val_unit); }
value skt_bind(value sock_v, value addr_v) { int ret; union sock_addr_union addr; socklen_param_type addr_len; get_sockaddr(addr_v, &addr, &addr_len); ret = bind(Socket_val(sock_v), (struct sockaddr*) &addr.s_inet, addr_len); if (ret == -1) serror("bind"); SKTTRACE(("bind\n")); return Val_unit; }
value skt_connect(value sock_v, value address){ union sock_addr_union addr; socklen_param_type addr_len; int ret; get_sockaddr(address, &addr, &addr_len); ret = WSAConnect(Socket_val(sock_v), (struct sockaddr*) &addr.s_inet, addr_len, NULL, NULL, NULL, NULL); if (ret < 0) serror("skt_connect") ; SKTTRACE(("skt_connect\n")); return Val_unit; }
bool f_socket_getsockname(CObjRef socket, VRefParam address, VRefParam port /* = null */) { Socket *sock = socket.getTyped<Socket>(); sockaddr_storage sa_storage; socklen_t salen = sizeof(sockaddr_storage); struct sockaddr *sa = (struct sockaddr *)&sa_storage; if (getsockname(sock->fd(), sa, &salen) < 0) { SOCKET_ERROR(sock, "unable to retrieve peer name", errno); return false; } return get_sockaddr(sa, address, port); }
uint16_t id_table::get_port(uint16_t id) { uint8_t f = get_family(id); struct sockaddr_storage* ss = get_sockaddr(id); if (f == AF_INET) { return ((struct sockaddr_in*)ss)->sin_port; } else if (f == AF_INET6){ return ((struct sockaddr_in6*)ss)->sin6_port; } else { return 0; } }
struct in6_addr* id_table::get_addr6(uint16_t id) { uint8_t f = get_family(id); if (f != AF_INET6) { return NULL; } struct sockaddr_storage* ss = get_sockaddr(id); if (ss != NULL) { return &(((struct sockaddr_in6*)ss)->sin6_addr); } else { return NULL; } }
bool HHVM_FUNCTION(socket_getsockname, const Resource& socket, VRefParam address, VRefParam port /* = null */) { auto sock = cast<Socket>(socket); sockaddr_storage sa_storage; socklen_t salen = sizeof(sockaddr_storage); struct sockaddr *sa = (struct sockaddr *)&sa_storage; if (getsockname(sock->fd(), sa, &salen) < 0) { SOCKET_ERROR(sock, "unable to retrieve peer name", errno); return false; } return get_sockaddr(sa, salen, address, port); }
void run_all(apr_pool_t *pool, int argc, const char * const *argv) { apr_sockaddr_t *sockaddr; if (argc != 1) { THROW(MESSAGE_ARGUMENT_INVALID); } DownloadFlowController flow_controller; show_line(); sockaddr = get_sockaddr(pool, DUMMY_ADDRESS); run_can_download(&flow_controller, sockaddr); }
CAMLprim value bigstring_sendto_nonblocking_no_sigpipe_stub( value v_fd, value v_pos, value v_len, value v_bstr, value v_addr) { char *bstr = get_bstr(v_bstr, v_pos); union sock_addr_union addr; socklen_param_type addr_len = sizeof(addr); ssize_t ret; get_sockaddr(v_addr, &addr, &addr_len); ret = sendto( Int_val(v_fd), bstr, Long_val(v_len), nonblocking_no_sigpipe_flag, &addr.s_gen, addr_len); if (ret == -1 && errno != EAGAIN && errno != EWOULDBLOCK) uerror("sendto_nonblocking_no_sigpipe", Nothing); return Val_long(ret); }
bool id_table::set_addr4(uint16_t id, struct in_addr addr) { struct sockaddr_storage* ss = get_sockaddr(id); if (ss == NULL) { return false; } uint8_t f = ss->ss_family; if (f == AF_INET) { ((struct sockaddr_in*)ss)->sin_addr = addr; return true; } if (f == AF_INET6) { return false; } else { return false; } }
bool id_table::set_port(uint16_t id, uint16_t port) { struct sockaddr_storage* ss = get_sockaddr(id); if (ss == NULL) { return false; } uint8_t f = ss->ss_family; if (f == AF_INET) { ((struct sockaddr_in*)ss)->sin_port = port; return true; } if (f == AF_INET6) { ((struct sockaddr_in6*)ss)->sin6_port = port; return true; } else { return false; } }
int get_client_socket(const char* ip, int port){ int socket_fd; struct in_addr iaddr; struct sockaddr_in address; socket_fd = get_socket_fd(); if(inet_aton(ip, &iaddr)==0){ perror("inet aton failed"); exit(EXIT_FAILURE); } address = get_sockaddr(port, iaddr.s_addr); if(connect(socket_fd, (struct sockaddr*) &address, sizeof(address))<0){ perror("Connect failed"); exit(EXIT_FAILURE); } return socket_fd; }
int cliser_server(lua_State *L) { #ifdef USE_CUDA // sometimes cutorch is loaded late, this is a good spot to try and register... Lcliser_CudaInit(L); #endif const char *host = luaL_optstring(L, 1, DEFAULT_HOST); int port = luaL_optinteger(L, 2, 0); char port_str[16]; snprintf(port_str, 16, "%d", port); struct sockaddr addr; socklen_t addrlen = sizeof(struct sockaddr); int ret = get_sockaddr(L, host, port != 0 ? port_str : NULL, &addr, &addrlen); if (ret) return ret; ret = socket(PF_INET, SOCK_STREAM, 0); if (ret <= 0) return LUA_HANDLE_ERROR(L, errno); int sock = ret; ret = bind(sock, &addr, addrlen); if (ret) { close(sock); return LUA_HANDLE_ERROR(L, errno); } ret = listen(sock, 1024); if (ret) { close(sock); return LUA_HANDLE_ERROR(L, errno); } struct sockaddr_in sin; addrlen = sizeof(struct sockaddr_in); ret = getsockname(sock, (struct sockaddr *)&sin, &addrlen); if (ret) { close(sock); return LUA_HANDLE_ERROR(L, errno); } port = ntohs(sin.sin_port); server_t *server = (server_t *)lua_newuserdata(L, sizeof(server_t)); memset(server, 0, sizeof(server_t)); server->sock = sock; server->ip_address = sin.sin_addr.s_addr; luaL_getmetatable(L, "ipc.server"); lua_setmetatable(L, -2); lua_pushinteger(L, port); return 2; }
int main(int argc, char *argv[]) { int numbytes; char sendBuff[MAX_MSG_SIZE]; char recvBuff[MAX_MSG_SIZE]; struct sockaddr_in serv_addr; struct hostent *server; int rv; int a, b, sum; if(argc != 3) { printf("\n Usage: %s hostname port \n",argv[0]); return 1; } struct addrinfo* results = get_sockaddr(argv[1], argv[2]); int sockfd = open_connection(results); memset(sendBuff, '0',sizeof(sendBuff)); memset(recvBuff, '0',sizeof(recvBuff)); a = 5; b = 10; snprintf(sendBuff, sizeof(sendBuff), "%d %d", a,b); write(sockfd, sendBuff, strlen(sendBuff)); numbytes = recv(sockfd,recvBuff,sizeof(recvBuff)-1,0); if (numbytes == -1){ perror("recv"); exit(1); } recvBuff[numbytes] = '\0'; sscanf(recvBuff, "%d", &sum); printf("received sum is %d\n", sum); return 0; }
CAMLprim value unix_sendto_native(value sock, value buff, value ofs, value len, value flags, value dest) { int ret, cv_flags; long numbytes; char iobuf[UNIX_BUFFER_SIZE]; union sock_addr_union addr; socklen_param_type addr_len; cv_flags = convert_flag_list(flags, msg_flag_table); get_sockaddr(dest, &addr, &addr_len); numbytes = Long_val(len); if (numbytes > UNIX_BUFFER_SIZE) numbytes = UNIX_BUFFER_SIZE; memmove (iobuf, &Byte(buff, Long_val(ofs)), numbytes); enter_blocking_section(); ret = sendto(Int_val(sock), iobuf, (int) numbytes, cv_flags, &addr.s_gen, addr_len); leave_blocking_section(); if (ret == -1) uerror("sendto", Nothing); return Val_int(ret); }
int init_server_socket(int port){ int socket_fd, result; struct sockaddr_in address; address = get_sockaddr(port, htonl(INADDR_ANY)); socket_fd = get_socket_fd(); result = bind(socket_fd, (struct sockaddr*) &address, sizeof(address)); if(result != 0){ perror("Socket binding failed"); exit(EXIT_FAILURE); } result = listen(socket_fd, SOMAXCONN); if(result != 0){ perror("Socket listening start failed"); exit(EXIT_FAILURE); } return socket_fd; }
static void scan_ifs(struct ifreq *r, int cnt) { struct iface i, *pi; struct ifa a; char *err, *colon; unsigned fl; ip_addr netmask; int l, scope; sockaddr *sa; if_start_update(); for (cnt /= sizeof(struct ifreq); cnt; cnt--, r++) { int sec = 0; bzero(&i, sizeof(i)); bzero(&a, sizeof(a)); if (colon = strchr(r->ifr_name, ':')) { /* It's an alias -- let's interpret it as a secondary interface address */ sec = 1; *colon = 0; } strncpy(i.name, r->ifr_name, sizeof(i.name) - 1); if(ioctl(if_scan_sock, SIOCGIFADDR,r)<0) continue; get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL, 1); if (ipa_nonzero(a.ip)) { l = ipa_classify(a.ip); if (l < 0 || !(l & IADDR_HOST)) { log(L_ERR "%s: Invalid interface address", i.name); a.ip = IPA_NONE; } else { a.scope = l & IADDR_SCOPE_MASK; if (a.scope == SCOPE_HOST) i.flags |= IF_LOOPBACK | IF_IGNORE; } } if (ioctl(if_scan_sock, SIOCGIFFLAGS, r) < 0) { err = "SIOCGIFFLAGS"; faulty: log(L_ERR "%s(%s): %m", err, i.name); bad: i.flags = (i.flags & ~IF_LINK_UP) | IF_ADMIN_DOWN; continue; } fl = r->ifr_flags; if (fl & IFF_UP) i.flags |= IF_LINK_UP; if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0) { err = "SIOCGIFNETMASK"; goto faulty; } get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL, 0); l = ipa_mklen(netmask); if (l < 0 || l == 31) { log(L_ERR "%s: Invalid netmask (%x)", i.name, netmask); goto bad; } a.pxlen = l; if (fl & IFF_POINTOPOINT) { a.flags |= IA_UNNUMBERED; if (ioctl(if_scan_sock, SIOCGIFDSTADDR, r) < 0) { err = "SIOCGIFDSTADDR"; goto faulty; } get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL, 1); a.prefix = a.opposite; a.pxlen = BITS_PER_IP_ADDRESS; } else a.prefix = ipa_and(a.ip, ipa_mkmask(a.pxlen)); if (fl & IFF_LOOPBACK) i.flags |= IF_LOOPBACK | IF_IGNORE; if (1 #ifndef CONFIG_ALL_MULTICAST && (fl & IFF_MULTICAST) #endif #ifndef CONFIG_UNNUM_MULTICAST && !(a.flags & IA_UNNUMBERED) #endif ) i.flags |= IF_MULTICAST; scope = ipa_classify(a.ip); if (scope < 0) { log(L_ERR "%s: Invalid address", i.name); goto bad; } a.scope = scope & IADDR_SCOPE_MASK; if (a.pxlen < 32) { a.brd = ipa_or(a.prefix, ipa_not(ipa_mkmask(a.pxlen))); if (ipa_equal(a.ip, a.prefix) || ipa_equal(a.ip, a.brd)) { log(L_ERR "%s: Using network or broadcast address for interface", i.name); goto bad; } if (fl & IFF_BROADCAST) i.flags |= IF_BROADCAST; if (a.pxlen < 30) i.flags |= IF_MULTIACCESS; else a.opposite = ipa_opposite(a.ip, a.pxlen); } else a.brd = a.opposite; a.scope = SCOPE_UNIVERSE; if (ioctl(if_scan_sock, SIOCGIFMTU, r) < 0) { err = "SIOCGIFMTU"; goto faulty; } i.mtu = r->ifr_mtu; #ifdef SIOCGIFINDEX if (ioctl(if_scan_sock, SIOCGIFINDEX, r) >= 0) i.index = r->ifr_ifindex; else if (errno != EINVAL) DBG("SIOCGIFINDEX failed: %m\n"); else /* defined, but not supported by the kernel */ #endif /* * The kernel doesn't give us real ifindices, but we still need them * at least for OSPF unnumbered links. So let's make them up ourselves. */ if (pi = if_find_by_name(i.name)) i.index = pi->index; else { static int if_index_counter = 1; i.index = if_index_counter++; } pi = NULL; if (sec) { a.flags |= IA_SECONDARY; pi = if_find_by_index(i.index); } if (!pi) pi = if_update(&i); a.iface = pi; ifa_update(&a); } if_end_update(); }
int main(int argc, char **argv) { srand(time(NULL)); int i, c; int pid_flags = 0; int mptcp = 0; int mtu = 0; char *user = NULL; char *local_port = NULL; char *local_addr = NULL; char *password = NULL; char *timeout = NULL; char *method = NULL; char *pid_path = NULL; char *conf_path = NULL; int remote_num = 0; ss_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; int option_index = 0; static struct option long_options[] = { { "mtu", required_argument, 0, 0 }, { "mptcp", no_argument, 0, 0 }, { "help", no_argument, 0, 0 }, { 0, 0, 0, 0 } }; opterr = 0; USE_TTY(); while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUvA6", long_options, &option_index)) != -1) { switch (c) { case 0: if (option_index == 0) { mtu = atoi(optarg); LOGI("set MTU to %d", mtu); } else if (option_index == 1) { mptcp = 1; LOGI("enable multipath TCP"); } else if (option_index == 2) { usage(); exit(EXIT_SUCCESS); } break; case 's': if (remote_num < MAX_REMOTE_NUM) { remote_addr[remote_num].host = optarg; remote_addr[remote_num++].port = NULL; } break; case 'p': remote_port = optarg; break; case 'l': local_port = optarg; break; case 'k': password = optarg; break; case 'f': pid_flags = 1; pid_path = optarg; break; case 't': timeout = optarg; break; case 'm': method = optarg; break; case 'c': conf_path = optarg; break; case 'b': local_addr = optarg; break; case 'a': user = optarg; break; #ifdef HAVE_SETRLIMIT case 'n': nofile = atoi(optarg); break; #endif case 'u': mode = TCP_AND_UDP; break; case 'U': mode = UDP_ONLY; break; case 'v': verbose = 1; break; case 'h': usage(); exit(EXIT_SUCCESS); case 'A': auth = 1; break; case '6': ipv6first = 1; break; case '?': // The option character is not recognized. LOGE("Unrecognized option: %s", optarg); opterr = 1; break; } } if (opterr) { usage(); exit(EXIT_FAILURE); } if (argc == 1) { if (conf_path == NULL) { conf_path = DEFAULT_CONF_PATH; } } if (conf_path != NULL) { jconf_t *conf = read_jconf(conf_path); if (remote_num == 0) { remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) remote_addr[i] = conf->remote_addr[i]; } if (remote_port == NULL) { remote_port = conf->remote_port; } if (local_addr == NULL) { local_addr = conf->local_addr; } if (local_port == NULL) { local_port = conf->local_port; } if (password == NULL) { password = conf->password; } if (method == NULL) { method = conf->method; } if (timeout == NULL) { timeout = conf->timeout; } if (user == NULL) { user = conf->user; } if (auth == 0) { auth = conf->auth; } if (mtu == 0) { mtu = conf->mtu; } if (mptcp == 0) { mptcp = conf->mptcp; } #ifdef HAVE_SETRLIMIT if (nofile == 0) { nofile = conf->nofile; } #endif } if (remote_num == 0 || remote_port == NULL || local_port == NULL || password == NULL) { usage(); exit(EXIT_FAILURE); } if (method == NULL) { method = "rc4-md5"; } if (timeout == NULL) { timeout = "600"; } #ifdef HAVE_SETRLIMIT /* * no need to check the return value here since we will show * the user an error message if setrlimit(2) fails */ if (nofile > 1024) { if (verbose) { LOGI("setting NOFILE to %d", nofile); } set_nofile(nofile); } #endif if (local_addr == NULL) { local_addr = "127.0.0.1"; } if (pid_flags) { USE_SYSLOG(argv[0]); daemonize(pid_path); } if (ipv6first) { LOGI("resolving hostname to IPv6 address first"); } if (auth) { LOGI("onetime authentication enabled"); } // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); signal(SIGINT, signal_cb); signal(SIGTERM, signal_cb); // Setup keys LOGI("initializing ciphers... %s", method); int m = enc_init(password, method); // Setup proxy context listen_ctx_t listen_ctx; listen_ctx.remote_num = remote_num; listen_ctx.remote_addr = ss_malloc(sizeof(struct sockaddr *) * remote_num); for (int i = 0; i < remote_num; i++) { char *host = remote_addr[i].host; char *port = remote_addr[i].port == NULL ? remote_port : remote_addr[i].port; struct sockaddr_storage *storage = ss_malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); if (get_sockaddr(host, port, storage, 1, ipv6first) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; } listen_ctx.timeout = atoi(timeout); listen_ctx.method = m; listen_ctx.mptcp = mptcp; struct ev_loop *loop = EV_DEFAULT; if (mode != UDP_ONLY) { // Setup socket int listenfd; listenfd = create_and_bind(local_addr, local_port); if (listenfd == -1) { FATAL("bind() error"); } if (listen(listenfd, SOMAXCONN) == -1) { FATAL("listen() error"); } setnonblocking(listenfd); listen_ctx.fd = listenfd; ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_start(loop, &listen_ctx.io); } // Setup UDP if (mode != TCP_ONLY) { LOGI("UDP relay enabled"); init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0], get_sockaddr_len(listen_ctx.remote_addr[0]), mtu, m, auth, listen_ctx.timeout, NULL); } if (mode == UDP_ONLY) { LOGI("TCP relay disabled"); } LOGI("listening at %s:%s", local_addr, local_port); // setuid if (user != NULL && ! run_as(user)) { FATAL("failed to switch user"); } if (geteuid() == 0){ LOGI("running from root user"); } ev_run(loop, 0); return 0; }
int main(int argc, char **argv) { int i, c; int pid_flags = 0; char *user = NULL; char *local_port = NULL; char *local_addr = NULL; char *password = NULL; char *timeout = NULL; char *method = NULL; char *pid_path = NULL; char *conf_path = NULL; int remote_num = 0; ss_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; opterr = 0; while ((c = getopt(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:uUvA")) != -1) switch (c) { case 's': if (remote_num < MAX_REMOTE_NUM) { remote_addr[remote_num].host = optarg; remote_addr[remote_num++].port = NULL; } break; case 'p': remote_port = optarg; break; case 'l': local_port = optarg; break; case 'k': password = optarg; break; case 'f': pid_flags = 1; pid_path = optarg; break; case 't': timeout = optarg; break; case 'm': method = optarg; break; case 'c': conf_path = optarg; break; case 'b': local_addr = optarg; break; case 'a': user = optarg; break; #ifdef HAVE_SETRLIMIT case 'n': nofile = atoi(optarg); break; #endif case 'u': mode = TCP_AND_UDP; break; case 'U': mode = UDP_ONLY; break; case 'v': verbose = 1; break; case 'A': auth = 1; break; } if (opterr) { usage(); exit(EXIT_FAILURE); } if (argc == 1) { if (conf_path == NULL) { conf_path = DEFAULT_CONF_PATH; } } if (conf_path != NULL) { jconf_t *conf = read_jconf(conf_path); if (remote_num == 0) { remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) remote_addr[i] = conf->remote_addr[i]; } if (remote_port == NULL) { remote_port = conf->remote_port; } if (local_addr == NULL) { local_addr = conf->local_addr; } if (local_port == NULL) { local_port = conf->local_port; } if (password == NULL) { password = conf->password; } if (method == NULL) { method = conf->method; } if (timeout == NULL) { timeout = conf->timeout; } if (auth == 0) { auth = conf->auth; } #ifdef HAVE_SETRLIMIT if (nofile == 0) { nofile = conf->nofile; } /* * no need to check the return value here since we will show * the user an error message if setrlimit(2) fails */ if (nofile > 1024) { if (verbose) { LOGI("setting NOFILE to %d", nofile); } set_nofile(nofile); } #endif } if (remote_num == 0 || remote_port == NULL || local_port == NULL || password == NULL) { usage(); exit(EXIT_FAILURE); } if (timeout == NULL) { timeout = "60"; } if (local_addr == NULL) { local_addr = "127.0.0.1"; } if (pid_flags) { USE_SYSLOG(argv[0]); daemonize(pid_path); } if (auth) { LOGI("onetime authentication enabled"); } // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); // Setup keys LOGI("initialize ciphers... %s", method); int m = enc_init(password, method); // Setup proxy context listen_ctx_t listen_ctx; listen_ctx.remote_num = remote_num; listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *) * remote_num); for (int i = 0; i < remote_num; i++) { char *host = remote_addr[i].host; char *port = remote_addr[i].port == NULL ? remote_port : remote_addr[i].port; struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); if (get_sockaddr(host, port, storage, 1) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; } listen_ctx.timeout = atoi(timeout); listen_ctx.method = m; struct ev_loop *loop = EV_DEFAULT; if (mode != UDP_ONLY) { // Setup socket int listenfd; listenfd = create_and_bind(local_addr, local_port); if (listenfd < 0) { FATAL("bind() error"); } if (listen(listenfd, SOMAXCONN) == -1) { FATAL("listen() error"); } setnonblocking(listenfd); listen_ctx.fd = listenfd; ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_start(loop, &listen_ctx.io); } // Setup UDP if (mode != TCP_ONLY) { LOGI("UDP relay enabled"); init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0], get_sockaddr_len(listen_ctx.remote_addr[0]), m, auth, listen_ctx.timeout, NULL); } if (mode == UDP_ONLY) { LOGI("TCP relay disabled"); } LOGI("listening at %s:%s", local_addr, local_port); // setuid if (user != NULL) { run_as(user); } ev_run(loop, 0); return 0; }
int main(int argc, char **argv) { int i, c; int pid_flags = 0; char *user = NULL; char *local_port = NULL; char *local_addr = NULL; char *password = NULL; char *timeout = NULL; char *method = NULL; char *pid_path = NULL; char *conf_path = NULL; char *iface = NULL; srand(time(NULL)); int remote_num = 0; ss_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; int option_index = 0; static struct option long_options[] = { { "fast-open", no_argument, 0, 0 }, { "acl", required_argument, 0, 0 }, { 0, 0, 0, 0 } }; opterr = 0; USE_TTY(); #ifdef ANDROID while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:uvVA", long_options, &option_index)) != -1) { #else while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:uvA", long_options, &option_index)) != -1) { #endif switch (c) { case 0: if (option_index == 0) { fast_open = 1; } else if (option_index == 1) { LOGI("initialize acl..."); acl = !init_acl(optarg); } break; case 's': if (remote_num < MAX_REMOTE_NUM) { remote_addr[remote_num].host = optarg; remote_addr[remote_num++].port = NULL; } break; case 'p': remote_port = optarg; break; case 'l': local_port = optarg; break; case 'k': password = optarg; break; case 'f': pid_flags = 1; pid_path = optarg; break; case 't': timeout = optarg; break; case 'm': method = optarg; break; case 'c': conf_path = optarg; break; case 'i': iface = optarg; break; case 'b': local_addr = optarg; break; case 'a': user = optarg; break; case 'u': mode = TCP_AND_UDP; break; case 'v': verbose = 1; break; case 'A': auth = 1; break; #ifdef ANDROID case 'V': vpn = 1; break; #endif } } if (opterr) { usage(); exit(EXIT_FAILURE); } if (argc == 1) { if (conf_path == NULL) { conf_path = DEFAULT_CONF_PATH; } } if (conf_path != NULL) { jconf_t *conf = read_jconf(conf_path); if (remote_num == 0) { remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) { remote_addr[i] = conf->remote_addr[i]; } } if (remote_port == NULL) { remote_port = conf->remote_port; } if (local_addr == NULL) { local_addr = conf->local_addr; } if (local_port == NULL) { local_port = conf->local_port; } if (password == NULL) { password = conf->password; } if (method == NULL) { method = conf->method; } if (timeout == NULL) { timeout = conf->timeout; } if (fast_open == 0) { fast_open = conf->fast_open; } #ifdef HAVE_SETRLIMIT if (nofile == 0) { nofile = conf->nofile; } /* * no need to check the return value here since we will show * the user an error message if setrlimit(2) fails */ if (nofile) { if (verbose) { LOGI("setting NOFILE to %d", nofile); } set_nofile(nofile); } #endif } if (remote_num == 0 || remote_port == NULL || local_port == NULL || password == NULL) { usage(); exit(EXIT_FAILURE); } if (timeout == NULL) { timeout = "60"; } if (local_addr == NULL) { local_addr = "127.0.0.1"; } if (pid_flags) { USE_SYSLOG(argv[0]); daemonize(pid_path); } if (fast_open == 1) { #ifdef TCP_FASTOPEN LOGI("using tcp fast open"); #else LOGE("tcp fast open is not supported by this environment"); #endif } if (auth) { LOGI("onetime authentication enabled"); } #ifdef __MINGW32__ winsock_init(); #else // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); #endif struct ev_signal sigint_watcher; struct ev_signal sigterm_watcher; ev_signal_init(&sigint_watcher, signal_cb, SIGINT); ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM); ev_signal_start(EV_DEFAULT, &sigint_watcher); ev_signal_start(EV_DEFAULT, &sigterm_watcher); // Setup keys LOGI("initialize ciphers... %s", method); int m = enc_init(password, method); // Setup proxy context struct listen_ctx listen_ctx; listen_ctx.remote_num = remote_num; listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *) * remote_num); for (i = 0; i < remote_num; i++) { char *host = remote_addr[i].host; char *port = remote_addr[i].port == NULL ? remote_port : remote_addr[i].port; struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); if (get_sockaddr(host, port, storage, 1) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; } listen_ctx.timeout = atoi(timeout); listen_ctx.iface = iface; listen_ctx.method = m; struct ev_loop *loop = EV_DEFAULT; // Setup socket int listenfd; listenfd = create_and_bind(local_addr, local_port); if (listenfd < 0) { FATAL("bind() error"); } if (listen(listenfd, SOMAXCONN) == -1) { FATAL("listen() error"); } setnonblocking(listenfd); listen_ctx.fd = listenfd; ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_start(loop, &listen_ctx.io); // Setup UDP if (mode != TCP_ONLY) { LOGI("udprelay enabled"); init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0], get_sockaddr_len(listen_ctx.remote_addr[0]), m, listen_ctx.timeout, iface); } LOGI("listening at %s:%s", local_addr, local_port); // setuid if (user != NULL) { run_as(user); } // Init connections cork_dllist_init(&connections); // Enter the loop ev_run(loop, 0); if (verbose) { LOGI("closed gracefully"); } // Clean up ev_io_stop(loop, &listen_ctx.io); free_connections(loop); if (mode != TCP_ONLY) { free_udprelay(); } for (i = 0; i < remote_num; i++) { free(listen_ctx.remote_addr[i]); } free(listen_ctx.remote_addr); #ifdef __MINGW32__ winsock_cleanup(); #endif ev_signal_stop(EV_DEFAULT, &sigint_watcher); ev_signal_stop(EV_DEFAULT, &sigterm_watcher); return 0; } #else int start_ss_local_server(profile_t profile) { srand(time(NULL)); char *remote_host = profile.remote_host; char *local_addr = profile.local_addr; char *method = profile.method; char *password = profile.password; char *log = profile.log; int remote_port = profile.remote_port; int local_port = profile.local_port; int timeout = profile.timeout; mode = profile.mode; fast_open = profile.fast_open; verbose = profile.verbose; char local_port_str[16]; char remote_port_str[16]; sprintf(local_port_str, "%d", local_port); sprintf(remote_port_str, "%d", remote_port); USE_LOGFILE(log); if (profile.acl != NULL) { acl = !init_acl(profile.acl); } if (local_addr == NULL) { local_addr = "127.0.0.1"; } #ifdef __MINGW32__ winsock_init(); #else // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); #endif struct ev_signal sigint_watcher; struct ev_signal sigterm_watcher; ev_signal_init(&sigint_watcher, signal_cb, SIGINT); ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM); ev_signal_start(EV_DEFAULT, &sigint_watcher); ev_signal_start(EV_DEFAULT, &sigterm_watcher); // Setup keys LOGI("initialize ciphers... %s", method); int m = enc_init(password, method); struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); if (get_sockaddr(remote_host, remote_port_str, storage, 1) == -1) { return -1; } // Setup proxy context struct ev_loop *loop = EV_DEFAULT; struct listen_ctx listen_ctx; listen_ctx.remote_num = 1; listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *)); listen_ctx.remote_addr[0] = (struct sockaddr *)storage; listen_ctx.timeout = timeout; listen_ctx.method = m; listen_ctx.iface = NULL; // Setup socket int listenfd; listenfd = create_and_bind(local_addr, local_port_str); if (listenfd < 0) { ERROR("bind()"); return -1; } if (listen(listenfd, SOMAXCONN) == -1) { ERROR("listen()"); return -1; } setnonblocking(listenfd); listen_ctx.fd = listenfd; ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_start(loop, &listen_ctx.io); // Setup UDP if (mode != TCP_ONLY) { LOGI("udprelay enabled"); struct sockaddr *addr = (struct sockaddr *)storage; init_udprelay(local_addr, local_port_str, addr, get_sockaddr_len(addr), m, timeout, NULL); } LOGI("listening at %s:%s", local_addr, local_port_str); // Init connections cork_dllist_init(&connections); // Enter the loop ev_run(loop, 0); if (verbose) { LOGI("closed gracefully"); } // Clean up if (mode != TCP_ONLY) { free_udprelay(); } ev_io_stop(loop, &listen_ctx.io); free_connections(loop); close(listen_ctx.fd); free(listen_ctx.remote_addr); #ifdef __MINGW32__ winsock_cleanup(); #endif ev_signal_stop(EV_DEFAULT, &sigint_watcher); ev_signal_stop(EV_DEFAULT, &sigterm_watcher); // cannot reach here return 0; }