static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* path) { #ifndef _WIN32 int status; int sockfd; struct sockaddr_un addr; rdpListener* listener = (rdpListener*) instance->listener; HANDLE hevent; if (listener->num_sockfds == MAX_LISTENER_HANDLES) { WLog_ERR(TAG, "too many listening sockets"); return FALSE; } sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd == -1) { WLog_ERR(TAG, "socket"); return FALSE; } fcntl(sockfd, F_SETFL, O_NONBLOCK); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, path, sizeof(addr.sun_path)); unlink(path); status = _bind(sockfd, (struct sockaddr*) &addr, sizeof(addr)); if (status != 0) { WLog_ERR(TAG, "bind"); closesocket((SOCKET) sockfd); return FALSE; } status = _listen(sockfd, 10); if (status != 0) { WLog_ERR(TAG, "listen"); closesocket((SOCKET) sockfd); return FALSE; } hevent = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd, WINPR_FD_READ); if (!hevent) { WLog_ERR(TAG, "failed to create sockfd event"); closesocket((SOCKET) sockfd); return FALSE; } listener->sockfds[listener->num_sockfds] = sockfd; listener->events[listener->num_sockfds] = hevent; listener->num_sockfds++; WLog_INFO(TAG, "Listening on socket %s.", addr.sun_path); return TRUE; #else return TRUE; #endif }
static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_address, UINT16 port) { int status; int sockfd; char addr[64]; void* sin_addr; int option_value; char servname[16]; struct addrinfo* ai; struct addrinfo* res; struct addrinfo hints = { 0 }; rdpListener* listener = (rdpListener*) instance->listener; #ifdef _WIN32 u_long arg; #endif hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (!bind_address) hints.ai_flags = AI_PASSIVE; sprintf_s(servname, sizeof(servname), "%d", port); status = getaddrinfo(bind_address, servname, &hints, &res); if (status != 0) { #ifdef _WIN32 WLog_ERR("getaddrinfo error: %s", gai_strerrorA(status)); #else WLog_ERR(TAG, "getaddrinfo"); #endif return FALSE; } for (ai = res; ai && (listener->num_sockfds < 5); ai = ai->ai_next) { if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue; if (listener->num_sockfds == MAX_LISTENER_HANDLES) { WLog_ERR(TAG, "too many listening sockets"); continue; } sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sockfd == -1) { WLog_ERR(TAG, "socket"); continue; } if (ai->ai_family == AF_INET) sin_addr = &(((struct sockaddr_in*) ai->ai_addr)->sin_addr); else sin_addr = &(((struct sockaddr_in6*) ai->ai_addr)->sin6_addr); inet_ntop(ai->ai_family, sin_addr, addr, sizeof(addr)); option_value = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &option_value, sizeof(option_value)) == -1) WLog_ERR(TAG, "setsockopt"); #ifndef _WIN32 fcntl(sockfd, F_SETFL, O_NONBLOCK); #else arg = 1; ioctlsocket(sockfd, FIONBIO, &arg); #endif status = _bind((SOCKET) sockfd, ai->ai_addr, ai->ai_addrlen); if (status != 0) { closesocket((SOCKET) sockfd); continue; } status = _listen((SOCKET) sockfd, 10); if (status != 0) { WLog_ERR(TAG, "listen"); closesocket((SOCKET) sockfd); continue; } /* FIXME: these file descriptors do not work on Windows */ listener->sockfds[listener->num_sockfds] = sockfd; listener->events[listener->num_sockfds] = WSACreateEvent(); if (!listener->events[listener->num_sockfds]) { listener->num_sockfds = 0; break; } WSAEventSelect(sockfd, listener->events[listener->num_sockfds], FD_READ | FD_ACCEPT | FD_CLOSE); listener->num_sockfds++; WLog_INFO(TAG, "Listening on %s:%s", addr, servname); } freeaddrinfo(res); return (listener->num_sockfds > 0 ? TRUE : FALSE); }
void bind() { _bind(); }
//----------------------------------------------------------------------------- bool Conf::load(const char* cfgFile) { FILE* pf; char locations[512]; ::sprintf(locations,"/etc/%s",cfgFile); pf = _ttfopen(locations, "rb"); if(pf) goto done; ::sprintf(locations,"/home/%s/.%s",getenv("USER"),cfgFile); pf = _ttfopen(locations, "rb"); if(pf) goto done; pf = _ttfopen(cfgFile, "rb"); done: if(pf) { AutoCall<int (*)(FILE*), FILE*> _a(::fclose, pf); char pred[128]; char val[128]; char line[512]; bool in_comment = false; try { while(!::feof(pf)) { if(::fgets(line,512,pf)) { ::str_prepline(line); if(*line==0) continue; if(in_comment || *line=='#') continue; const char* pnext = ::str_ccpy(pred, line,'='); if(*pred=='[') { str_lrtim(pred); _section = pred; continue; } else if(*pred=='}') { _assign("}", " ", 0); } if(pnext && *pnext) { ::str_scpy(val, (char*)pnext+1, "#"); ::str_lrtim(val); ::str_lrtim(pred); //cheak the logs folder if(pred[0]=='l') _bind(pred, "logs_path", _logs_path, val); _assign(pred, val, 0); } } else break; if(feof(pf)) { break; } } } catch(int& err) { ;//noting } } else { printf( "Cannot find configuration file in any of /etc/, ~/. and ./. \r\n"); //exit(0); } return finalize(); }
//----------------------------------------------------------------------------- void ConfPrx::_assign( const char* pred, const char* val, int line) { char lpred[256]; char loco[256]; ::strcpy(loco,val); ::strcpy(lpred,pred); try { if(_section.substr(1,::strlen(__VERSION)) == __VERSION) { BIND(_glb,runfrom); BIND(_glb,slog); BIND(_glb,nlogbytes); BIND(_glb,sessiontime); BIND(_glb,dnsssltout); BIND(_glb,bouncemax); BIND(_glb,authurl); BIND(_glb,usercontrol); BIND(_glb,reloadacls); BIND(_glb, hostsfile); BIND(_glb, hostsfilerule); BIND(_glb, openacl); //overwrites the non openacl ports. BIND(_glb, admins); BIND(_glb, maxrecs); BIND(_glb, domrecs); BIND(_glb, banned_ips); BIND(_glb, tickfile) BIND(_glb, jumpip); BIND(_glb, subscribers); if(lpred[0]=='}') { if(!_glb.signature.empty()) { fix_path(_glb.signature); // _glb.signaturegz=_glb.signature.append(".gz"); std::ifstream t(_glb.signature); std::stringstream buffer; buffer << t.rdbuf(); _glb.signature = buffer.str(); t.close(); } _glb.blog=0; if(_glb.slog=="A") { _glb.blog=0xFFFFFFFF; } else { _glb.blog |= _glb.slog.find('I') == string::npos ? 0 : 0x1; _glb.blog |= _glb.slog.find('W') == string::npos ? 0 : 0x2; _glb.blog |= _glb.slog.find('E') == string::npos ? 0 : 0x4; _glb.blog |= _glb.slog.find('T') == string::npos ? 0 : 0x8; _glb.blog |= _glb.slog.find('D') == string::npos ? 0 : 0x10; _glb.blog |= _glb.slog.find('X') == string::npos ? 0 : 0x20; _glb.blog |= _glb.slog.find('H') == string::npos ? 0 : 0x40; } _blog = _glb.blog; for(auto & f : _glb.jumpip) { const SADDR_46& k=(f).first; SADDR_46& v=(f).second; GLOGI("Jump: " << IP2STR(k) <<" -> " << IP2STR(v) ); } _glb.sessiontime *= 60; _glb.dnsssltout *= 60; if(!_glb.authurl.empty()) _glb.authurl_ip = fromstringip(_glb.authurl ); else _glb.authurl_ip = fromstringip("127.0.0.1:80"); if(!_glb.tickfile.empty()) { FILE* pf = fopen(_glb.tickfile.c_str(),"wb"); if(pf) { ::fputs("#",pf); ::fclose(pf); } } } // eo section } if(_section == "[port]") { BIND(_ports,pending); BIND(_ports,bindaddr); BIND(_ports,port); BIND(_ports,blocking); BIND(_ports,socks); BIND(_ports,clientisssl); BIND(_ports,hostisssl); BIND(_ports, openacl); BIND(_ports, authtoken); BIND(_ports, redirect); BIND(_ports, conport); if(lpred[0]=='}') { if(_ports.openacl==-1) // open port, make it as global ACL. _ports.openacl = _glb.openacl; GLOGD("ACL:" <<_ports.socks <<"/" << _ports.port << ": " << _ports.openacl) ::fix(_ports.pending, 32, 256); ::fix(_ports.port, (size_t)64, (size_t)65534); if(_ports.socks=="DNSSOCK" || _ports.socks=="PASSTRU") { if(!_ports.redirect.empty()) { _ports.toaddr=fromstringip(_ports.redirect.c_str()); GLOGD("Port:" << _ports.port << " forward to " << _ports.toaddr.c_str() << ":" << _ports.toaddr.port()); } } // vector<Redirs> redirs; // vector<string> overs; _listeners.insert(_ports); _ports.clear(); } } if(_section == "[pool]") { _bind(lpred, "min_threads",_pool.min_threads, val); _bind(lpred, "max_threads",_pool.max_threads, val); _bind(lpred, "clients_perthread",_pool.clients_perthread, val); _bind(lpred, "min_queue",_pool.min_queue, val); _bind(lpred, "max_queue",_pool.max_queue, val); _bind(lpred, "time_out",_pool.time_out, val); _bind(lpred, "buffsize", _pool.buffsize, val); _bind(lpred, "socketsize", _pool.socketsize, val); if(lpred[0]=='}') { if(_pool.socketsize && _pool.socketsize < _pool.buffsize) { _pool.socketsize = _pool.buffsize; } if(_pool.min_threads==0) _pool.min_threads=1; if(_pool.max_threads < _pool.min_threads) _pool.max_threads = _pool.min_threads; #ifdef DEBUG _pool.min_threads =1; #endif } } if(_section == "[ssl]") { _bind(lpred, "ssl_lib", _ssl.ssl_lib, val); _bind(lpred, "crypto_lib", _ssl.crypto_lib, val); _bind(lpred, "srv_certificate_file",_ssl.sCert, val); _bind(lpred, "srv_certificate_key_file",_ssl.sPrivKey, val); _bind(lpred, "srv_certificate_chain_file",_ssl.sChain, val); _bind(lpred, "cli_certificate_key_file",_ssl.cPrivKey, val); _bind(lpred, "cli_certificate_file",_ssl.cCert, val); _bind(lpred, "ca_certificate_file",_ssl.sCaCert, val); BIND(_ssl, version); if(lpred[0]=='}') { fix_path(_ssl.sCert); fix_path(_ssl.sPrivKey); fix_path(_ssl.sChain); fix_path(_ssl.sCaCert); fix_path(_ssl.cPrivKey); fix_path(_ssl.cCert); fix_path(_ssl.cCsr); } } } catch(int done) {} }
//----------------------------------------------------------------------------- // this is a quick hack config loading. TO ??? chnage it in the future void Conf::_assign( kchar* pred, kchar* val, int line) { char lpred[1024]; char loco[1024]; StrRule s[] = {{"allow-deny",1},{"deny-allow",0},{"",0}}; strcpy(loco,val); strcpy(lpred,pred); str_trimall(lpred,' '); str_trimall(lpred,'\t'); try { if(_section == "[marius]") { _bind(lpred, "cache", _marius.cache, val); _bind(lpred, "runfrom", _marius.runfrom, val); _bind(lpred, "dedicated", _marius.dedicated, val); _bind(lpred, "plugflags", _marius.plugflags, val); _bind(lpred, "pending", _marius.pending, val); _bind(lpred, "order", _marius.order, val, s); _bind(lpred, "allow", _marius.allow, val); _bind(lpred, "deny", _marius.deny, val); if(lpred[0]=='}') { // // make some subfolders under cache // char subdirs[PATH_MAX]; if(_marius.runfrom.empty()) { char scwd[512]; getcwd(scwd,511); strcat(scwd,"/"); _marius.runfrom = scwd; } if(0!=chdir(_marius.runfrom.c_str())) { std::cout << "cannot change folder to: " << _marius.runfrom << "\n"; exit(-1); } else { //test write system("touch dummy"); struct stat s; if(0!=stat("dummy",&s)) { std::cout << "cannot write to folder: " << _marius.runfrom << "\n"; exit(-2); } unlink("dummy"); } if(_marius.cache.empty()) { _marius.cache = "cache/"; } if(_marius.cache[0]!='/') { string s = _marius.cache; _marius.cache = _marius.runfrom + s; } if(_marius.cache==_marius.runfrom) { std::cout << "invalid cache foder\n"; exit(0); } sprintf(subdirs,"rm -r %s", _marius.cache.c_str()); system(subdirs); mkdir(_marius.cache.c_str(),0755); sprintf(subdirs,"%shss/", _marius.cache.c_str()); mkdir(subdirs,0755); sprintf(subdirs,"%ssbin/", _marius.cache.c_str()); mkdir(subdirs,0755); sprintf(subdirs,"%stmp/", _marius.cache.c_str()); mkdir(subdirs,0755); sprintf(subdirs,"%scerts/", _marius.runfrom.c_str()); mkdir(subdirs,0755); sprintf(subdirs,"%srules/", _marius.runfrom.c_str()); mkdir(subdirs,0755); } } if(_section == "[modules]") { if(*loco && *lpred) { _extmodules[lpred] = loco; } } if(_section == "[pool]") { _bind(lpred, "min_threads",_pool.min_threads, val); _bind(lpred, "max_threads",_pool.max_threads, val); _bind(lpred, "clients_perthread",_pool.clients_perthread, val); _bind(lpred, "min_queue",_pool.min_queue, val); _bind(lpred, "max_queue",_pool.max_queue, val); _bind(lpred, "time_out",_pool.time_out, val); _bind(lpred, "cache_singletons",_pool.cache_singletons, val); } if(_section == "[host]") { _bind(lpred, "host", _lhost.host, val); _bind(lpred, "proxy", _lhost.proxy, val); _bind(lpred, "home", _lhost.home, val); _bind(lpred, "order", _lhost.order, val, s); _bind(lpred, "allow", _lhost.allow, val); _bind(lpred, "deny", _lhost.deny, val); _bind(lpred, "ls", _lhost.ls, val); _bind(lpred, "index", _lhost.index, val); _bind(lpred, "ssl", _lhost.ssl, val); _bind(lpred, "maxupload", _lhost.maxupload, val); if(lpred[0]=='}') { if(_lhost.home[0]!='/') { _lhost.home = _marius.runfrom+_lhost.home; } std::set<string>::iterator it = _lhost.ls.begin(); for(; it != _lhost.ls.end(); ++it) { if((*it)[0] != '/') { std::string ts(*it); (*it).assign(_marius.runfrom + ts); } } if(_lhost.home[_lhost.home.length()-1] == '/') _lhost.home = _lhost.home.substr(0,_lhost.home.length()-1); string hostname = _lhost.host; size_t pos = hostname.find(':'); _lhost.host = hostname.substr(0,pos); string ports = hostname.substr(pos+1); hostname = hostname.substr(0,pos); size_t redi = ports.find(','); if(redi != string::npos)//we have redirected port to port { _lhost.port = ::_ttatoi(ports.substr(0,redi).c_str()); _lhost.iptabled = ::_ttatoi(ports.substr(redi+1).c_str()); } else { _lhost.port = ::_ttatoi(ports.c_str()); } _hosts[hostname] = _lhost; } } if(_section == "[ssl]") { _bind(lpred, "ssl_lib", _ssl.ssl_lib, val); _bind(lpred, "crypto_lib", _ssl.crypto_lib, val); _bind(lpred, "certificate", _ssl.certificate, val); _bind(lpred, "chain", _ssl.chain, val); if(lpred[0]=='}') { if(!_ssl.certificate.empty() && _ssl.certificate[0]!='/') { string cert = _ssl.certificate; _ssl.certificate = _marius.runfrom + cert; } if(!_ssl.chain.empty() && _ssl.chain[0]!='/') { string chain = _ssl.chain; _ssl.chain = _marius.runfrom + chain; } /* if(_ssl.certificate.empty() || _ssl.certificate=="auto") { //generate a autosigned cert char destcert[512]; sprintf(destcert,"%sserts/mycert.pem", _marius.cache.c_str()); char cmd[1024]; sprintf(cmd,"openssl req -x509 -nodes -days 365 -newkey rsa:1024 " "-keyout %s -out %s",destcert,destcert); system(cmd); } */ } } } catch(int done) { } }
void syscall_handler() { static int free_vm_proc; int syscall_num; unsigned int mem_size; struct t_process_context* current_process_context; struct t_processor_reg processor_reg; int* params; char data; unsigned int on_exit_action; SAVE_PROCESSOR_REG //call can come from kernel mode (sleep) SWITCH_DS_TO_KERNEL_MODE on_exit_action=0; current_process_context=system.process_info->current_process->val; t_console_desc *console_desc=current_process_context->console_desc; syscall_num=processor_reg.eax; params=processor_reg.ecx; if (syscall_num==1) { params[0]=_fork(processor_reg); } else if (syscall_num==2) { params[1]=_malloc(params[0]); } else if (syscall_num==3) { _free(params[0]); } else if (syscall_num==150) { params[1]=_bigMalloc(params[0]); } else if (syscall_num==151) { _bigFree(params[0]); } else if (syscall_num==4) { _write_char(console_desc,params[0]); } else if (syscall_num==5) { data=_read_char(console_desc); *((char*)params[0])=data; if (data==NULL) { on_exit_action=1; } } else if (syscall_num==6) { _echo_char(console_desc,params[0]); } else if (syscall_num==7) { _enable_cursor(console_desc); } else if (syscall_num==8) { _disable_cursor(console_desc); } else if (syscall_num==9) { _update_cursor(console_desc); } else if (syscall_num==10) { _delete_char(console_desc); } else if (syscall_num==11) { _pause(); on_exit_action=1; } else if (syscall_num==12) { _awake(params[0]); } else if (syscall_num==13) { _exit(params[0]); on_exit_action=2; } else if (syscall_num==14) { params[2]=_exec(params[0],params[1]); } else if (syscall_num==15) { _sleep_time(params[0]); on_exit_action=1; } else if (syscall_num==18) { params[2]=_open(system.root_fs,(char*) params[0],params[1]); on_exit_action=1; } else if (syscall_num==19) { params[1]=_close(system.root_fs,params[0]); on_exit_action=1; } else if (syscall_num==20) { params[3]=_read(system.root_fs,params[0],params[1],params[2]); on_exit_action=1; } else if (syscall_num==21) { params[3]=_write(system.root_fs,(void*)params[0],params[1],params[2]); on_exit_action=1; } else if (syscall_num==22) { params[1]=_rm(system.root_fs,(char*)params[0]); on_exit_action=1; } else if (syscall_num==23) { params[1]=_mkdir(system.root_fs,params[0]); on_exit_action=1; } //syscall 24 and 25 test only else if (syscall_num==24) { t_io_request* io_request; io_request=kmalloc(sizeof(t_io_request)); io_request->device_desc=system.device_desc; io_request->sector_count=params[0]; io_request->lba=params[1]; io_request->io_buffer=params[2]; io_request->process_context=current_process_context; _read_28_ata(io_request); kfree(io_request); } else if (syscall_num==25) { t_io_request* io_request; io_request=kmalloc(sizeof(t_io_request)); io_request->device_desc=system.device_desc; io_request->sector_count=params[0]; io_request->lba=params[1]; io_request->io_buffer=params[2]; io_request->process_context=current_process_context; _write_28_ata(io_request); kfree(io_request); } else if (syscall_num==26) { params[1]=_chdir(system.root_fs,(char*) params[0]); on_exit_action=1; } else if (syscall_num==27) { params[2]=_stat(system.root_fs,(char*) params[0],params[1]); } else if (syscall_num==28) { params[1]=_open_socket(system.network_desc->socket_desc,params[0]); } else if (syscall_num==29) { params[3]=_bind(system.network_desc->socket_desc,params[0],params[1],params[2]); } else if (syscall_num==30) { params[5]=_recvfrom(system.network_desc->socket_desc,params[0],params[1],params[2],params[3],params[4]); } else if (syscall_num==31) { params[5]=_sendto(system.network_desc->socket_desc,params[0],params[1],params[2],params[3],params[4]); } else if (syscall_num==32) { params[1]=_close_socket(system.network_desc->socket_desc,params[0]); } else if (syscall_num==101) { on_exit_action=1; } else if (syscall_num==102) { _flush_ata_pending_request(); } //DEBUG WRAPPER else if (syscall_num==103) { check_free_mem(); } else if (syscall_num==104) { debug_network(params[0],params[1]); } else { panic(); } // EXIT_INT_HANDLER(on_exit_action,processor_reg) static struct t_process_context _current_process_context; static struct t_process_context _old_process_context; static struct t_process_context _new_process_context; static struct t_processor_reg _processor_reg; static unsigned int _action; // static short _ds; CLI // _ds=ds; _action=on_exit_action; _current_process_context=*(struct t_process_context*)system.process_info->current_process->val; _old_process_context=_current_process_context; _processor_reg=processor_reg; if (_action>0) { schedule(&_current_process_context,&_processor_reg); _new_process_context=*(struct t_process_context*)(system.process_info->current_process->val); _processor_reg=_new_process_context.processor_reg; SWITCH_PAGE_DIR(FROM_VIRT_TO_PHY(((unsigned int) _new_process_context.page_dir))) DO_STACK_FRAME(_processor_reg.esp-8); // unsigned int* xxx; // unsigned int* yyy; // unsigned int* zzz; // xxx=FROM_PHY_TO_VIRT(((unsigned int*)_new_process_context.page_dir)[0]) & 0xFFFFF000; // zzz=FROM_PHY_TO_VIRT(xxx[256]); if (_action==2) { DO_STACK_FRAME(_processor_reg.esp-8); // free_vm_process(_old_process_context.page_dir,INIT_VM_USERSPACE); free_vm_process(&_old_process_context); // if (_old_process_context.phy_add_space!=NULL) // { // buddy_free_page(&system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_add_space)); // buddy_free_page(system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_user_stack)); // } buddy_free_page(system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_kernel_stack)); } RESTORE_PROCESSOR_REG EXIT_SYSCALL_HANDLER }
int bind( int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) { #ifdef SO_REUSEPORT // parse environment property (just once) if (reuse_ports.count < 0){ char *env_reuse = getenv("PRIVBIND_REUSE_PORTS"); if (env_reuse == NULL){ reuse_ports.count = 0; }else{ if (parselist(env_reuse, &reuse_ports, 1, 65535) != 0){ reuse_ports.count = -1; return -1; } } } // get bind port int port = -1; if (my_addr->sa_family==AF_INET) port = (int) ntohs(((struct sockaddr_in *) my_addr)->sin_port); else if (my_addr->sa_family==AF_INET6) port = (int) ntohs(((struct sockaddr_in6 *) my_addr)->sin6_port); // check if we should setup SO_REUSEPORT for this port if (port != -1 && is_in_list(&reuse_ports, port)){ int optval = 1; int retval = setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); if (retval != 0) return retval; } #endif /* First of all, attempt the bind. We only need the socket if it fails with access denied */ int oret=_bind( sockfd, my_addr, addrlen ); if( oret==0 || errno!=EACCES ) return oret; /* In most cases, we can let the bind go through as is */ if( master_quit || (my_addr->sa_family!=AF_INET && my_addr->sa_family!=AF_INET6) || (my_addr->sa_family==AF_INET && addrlen<sizeof(struct sockaddr_in)) || (my_addr->sa_family==AF_INET6 && addrlen<sizeof(struct sockaddr_in6)) ) { errno=EACCES; return oret; } /* Prepare the ancillary data for passing the actual FD */ struct msghdr msghdr={.msg_name=NULL}; struct cmsghdr *cmsg; char buf[CMSG_SPACE(sizeof(int))]; int *fdptr; msghdr.msg_control=buf; msghdr.msg_controllen=sizeof(buf); cmsg=CMSG_FIRSTHDR(&msghdr); cmsg->cmsg_level=SOL_SOCKET; cmsg->cmsg_type=SCM_RIGHTS; cmsg->cmsg_len=CMSG_LEN(sizeof(int)); /* Initialize the payload */ fdptr=(int *)CMSG_DATA(cmsg); fdptr[0]=sockfd; msghdr.msg_controllen=cmsg->cmsg_len; /* Don't forget the data component */ struct ipc_msg_req request; struct iovec iov; msghdr.msg_iov=&iov; msghdr.msg_iovlen=1; iov.iov_base=&request; iov.iov_len=sizeof(request); request.type=MSG_REQ_BIND; /* Check family of the request, only INET and INET6 should make it here */ if (my_addr->sa_family==AF_INET) request.data.bind4.addr=*(struct sockaddr_in *) my_addr; else if (my_addr->sa_family==AF_INET6) request.data.bind6.addr=*(struct sockaddr_in6 *) my_addr; int retval=oret; if( acquire_lock(1) ) { if( sendmsg( COMM_SOCKET, &msghdr, MSG_NOSIGNAL )>0 ) { /* Request was sent - wait for reply */ struct ipc_msg_reply reply; if( recv( COMM_SOCKET, &reply, sizeof(reply), 0 )>0 ) { retval=reply.data.stat.retval; if( retval<0 ) errno=reply.data.stat.error; } else { /* It would appear that the other process has closed, just return the original retval */ master_cleanup(); } } else { /* An error has occured! */ if( errno==EPIPE || errno==ENOTCONN || errno==EBADF ) { master_cleanup(); } else { perror("privbind communication socket error"); master_cleanup(); } } acquire_lock(0); } /* Make sure we return the original errno, regardless of what caused us to fail */ if( retval!=0 ) errno=EACCES; return retval; }
/* * Bind a socket to a privileged IP port */ int bindresvport_sa(int sd, struct sockaddr *sa) { int old, error, af; struct sockaddr_storage myaddr; struct sockaddr_in *sin; #ifdef INET6 struct sockaddr_in6 *sin6; #endif int proto, portrange, portlow; u_int16_t *portp; socklen_t salen; if (sa == NULL) { salen = sizeof(myaddr); sa = (struct sockaddr *)&myaddr; if (_getsockname(sd, sa, &salen) == -1) return -1; /* errno is correctly set */ af = sa->sa_family; memset(sa, 0, salen); } else af = sa->sa_family; switch (af) { case AF_INET: proto = IPPROTO_IP; portrange = IP_PORTRANGE; portlow = IP_PORTRANGE_LOW; sin = (struct sockaddr_in *)sa; salen = sizeof(struct sockaddr_in); portp = &sin->sin_port; break; #ifdef INET6 case AF_INET6: proto = IPPROTO_IPV6; portrange = IPV6_PORTRANGE; portlow = IPV6_PORTRANGE_LOW; sin6 = (struct sockaddr_in6 *)sa; salen = sizeof(struct sockaddr_in6); portp = &sin6->sin6_port; break; #endif default: errno = EPFNOSUPPORT; return (-1); } sa->sa_family = af; sa->sa_len = salen; if (*portp == 0) { socklen_t oldlen = sizeof(old); error = _getsockopt(sd, proto, portrange, &old, &oldlen); if (error < 0) return (error); error = _setsockopt(sd, proto, portrange, &portlow, sizeof(portlow)); if (error < 0) return (error); } error = _bind(sd, sa, salen); if (*portp == 0) { int saved_errno = errno; if (error < 0) { if (_setsockopt(sd, proto, portrange, &old, sizeof(old)) < 0) errno = saved_errno; return (error); } if (sa != (struct sockaddr *)&myaddr) { /* Hmm, what did the kernel assign? */ if (_getsockname(sd, sa, &salen) < 0) errno = saved_errno; return (error); } } return (error); }
polynomial& polynomial::bind(polynomial& p, std::size_t i, double xi) { return _bind(p, i, xi); }
UDPServer::UDPServer(int port): _servport(port) { _sockfd = socket(AF_INET, SOCK_DGRAM, 0); _bind(); }