Skip to content

Commit 8a02b94

Browse files
committed
intra/tunnel: new crash output api
1 parent 20e1f68 commit 8a02b94

1 file changed

Lines changed: 36 additions & 9 deletions

File tree

intra/tun2socks.go

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"os"
2929
"runtime"
3030
"runtime/debug"
31+
"sync/atomic"
3132
"time"
3233

3334
x "github.com/celzero/firestack/intra/backend"
@@ -103,6 +104,7 @@ func SetupConsole(console Console) {
103104

104105
logfd := <-logch
105106
crashfd := <-crashch
107+
crashpiped.Store(crashfd)
106108

107109
log.ConsoleReady(ctx)
108110

@@ -315,14 +317,15 @@ func Crash(afterMs int64) {
315317

316318
// global references to keep go's finalizer from cleaning up the FDs
317319
var crashReader, crashWriter, crashRWErr = os.Pipe()
320+
var crashpiped atomic.Bool
318321

319322
func pipeCrashOutput(c Console) (ok bool) {
320323
if crashRWErr != nil {
321324
log.E("tun: err crash output pipe: %v", crashRWErr)
322325
return false
323326
}
324-
pipeBuffer64k(crashWriter)
325-
pipeBuffer64k(crashReader)
327+
pipeBuffer256k(crashWriter)
328+
pipeBuffer256k(crashReader)
326329
// defer core.Close(crashReader) // close iff r is dup'd by client code
327330
defer core.Close(crashWriter) // always close as w is dup'd by the runtime
328331
if setCrashFd(crashWriter) && c.CrashFD(int(crashReader.Fd())) {
@@ -336,27 +339,51 @@ func pipeCrashOutput(c Console) (ok bool) {
336339
func setCrashFd(f *os.File) (ok bool) {
337340
// f is dup()ed by debug.SetCrashOutput before use
338341
err := debug.SetCrashOutput(f, debug.CrashOptions{})
339-
logei(err)("tun: crash output file %s, err? %v", f.Name(), err)
342+
logei(err)("tun: crash output file %s, err? %v", fname(f), err)
340343
return err == nil
341344
}
342345

343-
func pipeBuffer64k(f *os.File) bool {
344-
const b64k = 64 * 1024
346+
// SetCrashOutput will set the crash output file to dup(fd), and return true if successful.
347+
// Disables crash output if fd is less than 3.
348+
func SetCrashOutput(fd int) bool {
349+
p := crashpiped.Swap(false)
350+
ok := setCrashFd(nil)
351+
// defer core.Close(crashReader) if fd not owned by the client
352+
log.I("tun: closing crash out... ok? %t; was piped? %t; new fd: %d", ok, p, fd)
353+
if fd >= 2 {
354+
return setCrashFd(os.NewFile(uintptr(fd), "ktcfd"))
355+
}
356+
return false
357+
}
358+
359+
func pipeBuffer256k(f *os.File) bool {
360+
if f == nil {
361+
return false
362+
}
363+
const b256k = 4 * 64 * 1024
345364
fd := f.Fd()
365+
nom := f.Name()
346366
// kernel may round this up to the nearest page size multiple?
347-
x, err := unix.FcntlInt(fd, unix.F_SETPIPE_SZ, b64k)
367+
x, err := unix.FcntlInt(fd, unix.F_SETPIPE_SZ, b256k)
348368
if err != nil {
349-
log.W("tun: err set pipe(%d) size %d: %v", fd, x, err)
369+
log.W("tun: pipe: (%s %d) err set size %d: %v", nom, fd, x, err)
350370
return false
351371
}
352372

353373
x, err = unix.FcntlInt(fd, unix.F_GETPIPE_SZ, 0)
354374
if err != nil {
355-
log.W("tun: err get pipe(%d) size: %v", fd, err)
375+
log.W("tun: pipe: (%s %d) err get size: %v", nom, fd, err)
356376
return false
357377
}
358378

359379
runtime.KeepAlive(f)
360-
log.W("tun: pipe(%d) buffer %s", fd, core.FmtBytes(uint64(x)))
380+
log.W("tun: pipe: (%s %d) buffer %s", nom, fd, core.FmtBytes(uint64(x)))
361381
return true
362382
}
383+
384+
func fname(f *os.File) string {
385+
if f == nil {
386+
return "<nil file>"
387+
}
388+
return f.Name()
389+
}

0 commit comments

Comments
 (0)