func tcpLoop() { listener, err := net.ListenTCP("tcp", transThis) if err != nil { kilog.Critical("%v", err.Error()) os.Exit(-1) } for { clnt, err := listener.AcceptTCP() if err != nil { kilog.Critical("%v", err.Error()) os.Exit(-1) } go func() { defer clnt.Close() defer clnt.CloseRead() defer clnt.CloseWrite() lol, err := clnt.File() if err != nil { panic(err.Error()) } haha := C.getdestaddr_iptables(C.int(lol.Fd())) lol.Close() sdf := make([]byte, 4) binary.LittleEndian.PutUint32(sdf, uint32(haha.sin_addr.s_addr)) port := binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&haha.sin_port))[:]) rmAddr := &net.TCPAddr{sdf, int(port), ""} dnsLock.Lock() rmName, ok := ipToName[rmAddr.IP.String()] dnsLock.Unlock() var rmConn io.ReadWriteCloser // see if we should connect IP or name if !ok { kilog.Warning("unmapped IP received (%v), misconfig?", rmAddr) rmConn, err = socksConnectIP(socksNext, rmAddr) } else { kilog.Debug("mapped IP received (%v -> %v)", rmAddr, rmName) rmConn, err = socksConnectName(socksNext, rmName, rmAddr.Port) } if err != nil { kilog.Debug("%v", err) return } defer rmConn.Close() go func() { defer rmConn.Close() defer clnt.Close() defer clnt.CloseRead() defer clnt.CloseWrite() io.Copy(rmConn, clnt) }() io.Copy(clnt, rmConn) kilog.Debug("closing client") }() } }
func NewSCServer(addr string) SCServer { listener, err := net.Listen("tcp", addr) if err != nil { panic(err.Error()) } killer := make(chan bool) go func() { for { select { case <-killer: listener.Close() return default: // establish connection client, err := listener.Accept() //log.Debug("Of acceptings client: %s", client.RemoteAddr()) if err != nil { kilog.Critical(err.Error()) client.Close() continue } go func() { err := sc_server_handler(client) if err != nil { //log.Error(err.Error()) } }() } } }() return SCServer{listener, killer} }
func reorder_messages(input, output chan sc_message) { defer close(output) ptr := uint64(0) buffer := make(map[uint64]sc_message) for { thing, ok := <-input if !ok { return } buffer[thing.seqnum] = thing if len(buffer) > 4096 { kilog.Critical("reorder_messages buffer blown") return } for { thing, ok := buffer[ptr] if !ok { break } delete(buffer, ptr) output <- thing ptr++ } } }
func dnsDispatch() { udpConn, err := net.ListenUDP("udp", dnsThis) if err != nil { kilog.Critical("%v", err.Error()) os.Exit(-1) } // hack to make Windows happy nameToIP["dns.msftncsi.com."] = "131.107.255.255" dns.ActivateAndServe(nil, udpConn, dns.HandlerFunc(dnsHandle)) }
func startSocks() { listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%v", socksPort)) if err != nil { kilog.Critical("failed to bind SOCKS5 listener: %v", err.Error()) os.Exit(-1) } go func() { for { clnt, err := listener.Accept() if err != nil { continue } go handleSocks(clnt) } }() kilog.Info("SOCKS5 listener successfully bound at %v", listener.Addr()) }
func startControl() { ctlState.prt2prv = make(map[int]natrium.EdDSAPrivate) ctlState.prt2lst = make(map[int]*kiricom.EasyListener) listener, err := net.Listen("tcp", "127.0.0.1:12377") if err != nil { kilog.Critical(err.Error()) os.Exit(-1) } go func() { for { incoming, err := listener.Accept() if err != nil { continue } go handleControl(incoming) } }() }
func handleControl(clnt io.ReadWriteCloser) { defer clnt.Close() greeting := ctlGreeting{0xCACACACA, ctlVersion{0, 0, 0}, socksPort} // 0.0.0 means unnumbered version err := struc.Pack(clnt, &greeting) if err != nil { kilog.Debug("unable to write control greeting: %v", err.Error()) return } var command ctlCommand err = struc.Unpack(clnt, &command) if err != nil { kilog.Debug("unable to read control command: %v", err.Error()) return } var response ctlResponse defer struc.Pack(clnt, &response) // do the actual work switch command.Verb { case ctlCmdNOOP: return case ctlCmdHOST: kilog.Debug("received control request to forward port %v to %v, with %v", command.IntPort, command.ExtPort, command.PrivKey) ctlState.RLock() _, ok := ctlState.prt2prv[command.ExtPort] ctlState.RUnlock() if ok { kilog.Debug("port %v already occupied, refusing request!", command.ExtPort) response.Verb = ctlRespNOPE response.Name = "port already occupied" return } ctlState.Lock() defer ctlState.Unlock() newlistnr, err := kiricom.EasyListen(fmt.Sprintf("0.0.0.0:%v", command.ExtPort), command.PrivKey, command.PrivKey.PublicKey()) kilog.Debug("startControl secret is %x", command.PrivKey.PublicKey()) if err != nil { kilog.Debug("could not create ICOM listener") response.Verb = ctlRespNOPE response.Name = err.Error() return } ctlState.prt2lst[command.ExtPort] = newlistnr ctlState.prt2prv[command.ExtPort] = command.PrivKey response.Verb = ctlRespOKAY pubip, err := getPublicIP() if err != nil { kilog.Critical("computer does not seem to have an Internet connection; dying!") os.Exit(-1) } response.Name = sagiriNames.EdgeID{command.PrivKey.PublicKey(), pubip, uint16(command.ExtPort)}.String() groop, err := newServGroup(command.PrivKey) if err != nil { kilog.Debug("host: could not start servGroup %v", err.Error()) return } // time to spin off threads to forward the connections handle := func(clnt io.ReadWriteCloser) { defer clnt.Close() fwd, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%v", command.IntPort)) if err != nil { kilog.Debug("host: could not forward %v", err.Error()) return } kilog.Debug("host: completed forwarding") defer fwd.Close() go func() { defer fwd.Close() defer clnt.Close() io.Copy(fwd, clnt) }() io.Copy(clnt, fwd) } go func() { defer newlistnr.Close() defer groop.Destroy() for { clnt, err := newlistnr.Accept() if err != nil { kilog.Debug("host: direct error %v", err.Error()) return } go handle(clnt) } }() go func() { defer groop.Destroy() defer newlistnr.Close() REDO: for { clnt, err := groop.Accept() if err != nil { kilog.Debug("host: onion error %v", err.Error()) groop.Destroy() groop, err = newServGroup(command.PrivKey) if err != nil { kilog.Debug(err.Error()) time.Sleep(time.Second) } goto REDO } go handle(clnt) } }() case ctlCmdSTOP: ctlState.Lock() defer ctlState.Unlock() _, ok := ctlState.prt2lst[command.ExtPort] if !ok { response.Verb = ctlRespNOPE response.Name = "no service with the given port" return } rlPriv := ctlState.prt2prv[command.ExtPort] if subtle.ConstantTimeCompare(rlPriv, command.PrivKey) != 1 { response.Verb = ctlRespNOPE response.Name = "given private key incorrect, refusing to remove" return } delete(ctlState.prt2prv, command.ExtPort) ctlState.prt2lst[command.ExtPort].Close() response.Verb = ctlRespOKAY } }
func main() { rand.Seed(time.Now().UnixNano()) go run_monitor_loop() flag.Parse() if *confloc == "" { kilog.Warning("No configuration file given, using defaults") } else { err := gcfg.ReadFileInto(&MasterConfig, *confloc) if err != nil { kilog.Warning("Configuration file broken, using defaults") } } if *singhop { MasterConfig.Network.MinCircuitLen = 1 } kilog.Info("Kirisurf %s started! mkh=%s", version, MasterKeyHash) set_gui_progress(0.1) kilog.Info("Bootstrapping 10%%: finding directory address...") dirclient.DIRADDR, _ = dirclient.FindDirectoryURL() set_gui_progress(0.2) kilog.Info("Bootstrapping 20%%: found directory address, refreshing directory...") err := dirclient.RefreshDirectory() if err != nil { kilog.Critical("Stuck at 20%%: directory connection error %s", err.Error()) for { time.Sleep(time.Second) } } set_gui_progress(0.3) kilog.Info("Bootstrapping 30%%: directory refreshed, beginning to build circuits...") go run_diagnostic_loop() dirclient.RefreshDirectory() if MasterConfig.General.Role == "server" { NewSCServer(MasterConfig.General.ORAddr) addr := RegisterNGSCServer(MasterConfig.General.ORAddr) prt, _ := strconv.Atoi( strings.Split(MasterConfig.General.ORAddr, ":")[1]) go func() { err := UPnPForwardAddr(MasterConfig.General.ORAddr) err = UPnPForwardAddr(addr) if err != nil { kilog.Warning("UPnP failed: %s", err) if MasterConfig.Network.OverrideUPnP { go dirclient.RunRelay(prt, MasterKeyHash, MasterConfig.General.IsExit) } return } kilog.Info("UPnP successfully forwarded port") go dirclient.RunRelay(prt, MasterKeyHash, MasterConfig.General.IsExit) }() kilog.Info("Started server!") if *noclient { for { time.Sleep(time.Second) } } } run_client_loop() kilog.Info("Kirisurf exited") }
func main() { kilog.Info("DANASI 0.1 starting...") var _dnsThis string var _dnsNext string flag.StringVar(&_dnsThis, "dnsThis", "127.0.0.1:53535", "address on which to listen for DNS") flag.StringVar(&_dnsNext, "dnsNext", "8.8.8.8:53", "address to which unrelated requests are forwarded") var _transThis string var _socksNext string flag.StringVar(&_transThis, "transThis", "127.0.0.1:12377", "address to which TCP connections in the IP range should be forwarded") flag.StringVar(&_socksNext, "socksNext", "127.0.0.1:2377", "SOCKS5 proxy with which matching names are dialed upon") var _ipRange string flag.StringVar(&_ipRange, "ipRange", "100.64.0.0/10", "IP range from which addresses are allocated") var _namePattern string flag.StringVar(&_namePattern, "namePattern", ".*", "regexp (POSIX) matching DNS names to be intercepted") flag.Parse() kilog.Debug("flags read:") kilog.Debug(" dnsThis = %v", _dnsThis) kilog.Debug(" dnsNext = %v", _dnsNext) kilog.Debug(" transThis = %v", _transThis) kilog.Debug(" socksNext = %v", _socksNext) kilog.Debug(" ipRange = %v", _ipRange) kilog.Debug(" namePattern = %v", _namePattern) var err error // validate the command-line arguments dnsThis, err = net.ResolveUDPAddr("udp", _dnsThis) if err != nil { kilog.Critical("*** malformed dnsThis: %v ***", err.Error()) os.Exit(-1) } dnsNext, err = net.ResolveUDPAddr("udp", _dnsNext) if err != nil { kilog.Critical("*** malformed dnsNext: %v ***", err.Error()) os.Exit(-1) } transThis, err = net.ResolveTCPAddr("tcp", _transThis) if err != nil { kilog.Critical("*** malformed transThis: %v ***", err.Error()) os.Exit(-1) } socksNext, err = net.ResolveTCPAddr("tcp", _socksNext) if err != nil { kilog.Critical("*** malformed socksNext: %v ***", err.Error()) os.Exit(-1) } _, ipRange, err = net.ParseCIDR(_ipRange) if err != nil { kilog.Critical("*** malformed ipRange: %v ***", err.Error()) os.Exit(-1) } namePattern, err = regexp.CompilePOSIX(_namePattern) if err != nil { kilog.Critical("*** malformed namePattern: %v ***", err.Error()) os.Exit(-1) } go dnsDispatch() tcpLoop() }