Beispiel #1
1
func childMain() error {
	var err error

	pipe := os.NewFile(uintptr(3), "pipe")
	if pipe != nil {
		defer pipe.Close()
		if err == nil {
			pipe.Write([]byte{DaemonSuccess})
		} else {
			pipe.Write([]byte{DaemonFailure})
		}
	}

	signal.Ignore(syscall.SIGCHLD)

	syscall.Close(0)
	syscall.Close(1)
	syscall.Close(2)

	syscall.Setsid()
	syscall.Umask(022)

	// syscall.Chdir("/")

	return nil
}
Beispiel #2
1
func listenStream(netw, addr string) (l net.Listener, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	// Set backlog size to the maximum
	if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if l, err = net.FileListener(file); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		l.Close()
		return nil, err
	}

	return l, err
}
Beispiel #3
0
func TestSelect(t *testing.T) {
	var p1, p2 [2]int
	mustNil(syscall.Pipe(p1[:]))
	mustNil(syscall.Pipe(p2[:]))
	fs := NewFdSet(p1[0], p2[0])
	var maxfd int
	if p1[0] > p2[0] {
		maxfd = p1[0] + 1
	} else {
		maxfd = p2[0] + 1
	}
	go func() {
		syscall.Write(p1[1], []byte("to p1"))
		syscall.Write(p2[1], []byte("to p2"))
		syscall.Close(p1[1])
		syscall.Close(p2[1])
	}()
	e := Select(maxfd+1, fs, nil, nil, nil)
	if e != nil {
		t.Errorf("Select(%v, %v, nil, nil, nil) => %v, want <nil>",
			maxfd+1, fs, e)
	}
	syscall.Close(p1[0])
	syscall.Close(p2[0])
}
Beispiel #4
0
func CaptureStream(file *os.File) (*os.File, func(), error) {
	pipeR, pipeW, err := os.Pipe()
	if err != nil {
		return nil, nil, err
	}

	bkupFD, err := syscall.Dup(int(file.Fd()))
	if err != nil {
		pipeW.Close()
		pipeR.Close()
		return nil, nil, err
	}

	err = syscall.Dup2(int(pipeW.Fd()), int(file.Fd()))
	if err != nil {
		syscall.Close(bkupFD)
		pipeW.Close()
		pipeR.Close()
	}

	cleanFunc := func() {
		syscall.Dup2(bkupFD, int(file.Fd()))
		syscall.Close(bkupFD)
		pipeW.Close()
		pipeR.Close()
	}

	return pipeR, cleanFunc, nil
}
Beispiel #5
0
func (sc *selectCtx) Init() error {
	sc.rset.Zero()
	sc.wset.Zero()
	sc.fdmax = -1
	// Create and configure the pipe-ends.
	b := make([]int, 2)
	err := syscall.Pipe(b)
	if err != nil {
		return err
	}
	sc.pfdr, sc.pfdw = b[0], b[1]
	syscall.CloseOnExec(sc.pfdr)
	syscall.CloseOnExec(sc.pfdw)
	err = syscall.SetNonblock(sc.pfdr, true)
	if err != nil {
		syscall.Close(sc.pfdr)
		syscall.Close(sc.pfdw)
		return err
	}
	err = syscall.SetNonblock(sc.pfdw, true)
	if err != nil {
		syscall.Close(sc.pfdr)
		syscall.Close(sc.pfdw)
		return err
	}
	// pfdr (read-end of pipe) is set (and remains set forever) on
	// rset.
	sc.rset.Set(sc.pfdr)
	sc.fdmax = sc.pfdr
	// allocate dummy selectCtx.{b,b1} buffers.
	sc.b = make([]byte, 1)
	sc.b1 = make([]byte, 128)
	return nil
}
Beispiel #6
0
// Close wraps syscall.Close.
func (sw *Switch) Close(s int) (err error) {
	so := sw.sockso(s)
	if so == nil {
		return syscall.Close(s)
	}
	sw.fmu.RLock()
	f, _ := sw.fltab[FilterClose]
	sw.fmu.RUnlock()

	af, err := f.apply(so)
	if err != nil {
		return err
	}
	so.Err = syscall.Close(s)
	if err = af.apply(so); err != nil {
		return err
	}

	if so.Err != nil {
		return so.Err
	}
	sw.smu.Lock()
	delete(sw.sotab, s)
	sw.stats.getLocked(so.Cookie).Closed++
	sw.smu.Unlock()
	return nil
}
Beispiel #7
0
func main() {
	args := Arguments()

	infile, args, err := args.String("in-file", nil)
	Check(err)
	outfile, args, err := args.String("out-file", nil)
	Check(err)

	infd, err := syscall.Open(infile, int(ReadOnly), 0)
	Check(err)
	defer func() { Check(syscall.Close(infd)) }()

	flags := Create | WriteOnly | Truncate
	perms := 0 |
		UserRead | UserWrite |
		GroupRead | GroupWrite |
		OtherRead | OtherWrite
	outfd, err := syscall.Open(outfile, int(flags), uint32(perms))
	Check(err)
	defer func() { Check(syscall.Close(outfd)) }()

	bufSize := 1024
	buf := make([]byte, bufSize)
	var n int
	for {
		n, err = syscall.Read(infd, buf)
		Check(err)
		if n == 0 {
			break
		}
		_, err = syscall.Write(outfd, buf[:n])
		Check(err)
	}
}
Beispiel #8
0
func (s *Splicer) CopyBytes(in, out *net.TCPConn) {
	// Close the tcp connection given to us.
	defer func() {
		// TODO: Double close problems?
		out.Close()
		in.Close()
	}()

	// Invoking File() on the connection will duplicate the socket fd, setting
	// the original (socket fd) to block.
	inFile, err := in.File()
	if err != nil {
		log.Fatal(err)
	}
	inFD := int(inFile.Fd())
	defer syscall.Close(inFD)

	outFile, err := out.File()
	if err != nil {
		log.Fatal(err)
	}
	outFD := int(outFile.Fd())
	defer syscall.Close(outFD)

	var wg sync.WaitGroup
	wg.Add(2)
	go s.splice(fmt.Sprintf("from backend: %v -> %v", in.RemoteAddr(), out.RemoteAddr()), inFD, outFD, &wg)
	go s.splice(fmt.Sprintf("to backend: %v -> %v", out.RemoteAddr(), in.RemoteAddr()), outFD, inFD, &wg)
	wg.Wait()
}
Beispiel #9
0
func main() {
	fd := make([]int, 2)
	if err := syscall.Pipe(fd); err != nil {
		log.Fatal("Socketpair:", err)
	}
	defer syscall.Close(fd[0])
	defer syscall.Close(fd[1])
	name := fmt.Sprintf("/proc/%d/fd/%d", os.Getpid(), fd[1])
	fmt.Println(name)

	cmd := exec.Command("ubertooth-btle", "-f", "-d", name)
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}

	f := os.NewFile(uintptr(fd[0]), "server")
	buf := make([]byte, 1024)
	for {
		n, err := f.Read(buf)
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%q\n", buf[:n])
	}
}
Beispiel #10
0
/*
	c.sa = new(syscall.SockaddrInet4)
	c.sa.Addr = [4]byte{10, 1, 1, 131}
	c.sa.Port = port
*/
func (c *Worker) socket() {
	begin := time.Now()
	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0)
	if err != nil {
		syscall.Close(s)
		return
	}

	err = syscall.Connect(s, nil) //TODO
	if err != nil {
		lg(err)
		syscall.Close(s)
		return
	}

	_, err = syscall.Write(s, message.content)
	if err != nil {
		syscall.Close(s)
		return
	}

	_, err = syscall.Read(s, c.data)
	if err != nil {
		syscall.Close(s)
		return
	}

	syscall.Close(s)
	time.Now().Sub(begin)
}
Beispiel #11
0
func ListenPipe(path, sddl string) (net.Listener, error) {
	var (
		sd  []byte
		err error
	)
	if sddl != "" {
		sd, err = sddlToSecurityDescriptor(sddl)
		if err != nil {
			return nil, err
		}
	}
	h, err := makeServerPipeHandle(path, sd, true)
	if err != nil {
		return nil, err
	}
	// Immediately open and then close a client handle so that the named pipe is
	// created but not currently accepting connections.
	h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
	if err != nil {
		syscall.Close(h)
		return nil, err
	}
	syscall.Close(h2)
	l := &win32PipeListener{
		firstHandle:        h,
		path:               path,
		securityDescriptor: sd,
		acceptCh:           make(chan (chan acceptResponse)),
		closeCh:            make(chan int),
		doneCh:             make(chan int),
	}
	go l.listenerRoutine()
	return l, nil
}
Beispiel #12
0
func afterDaemonize(err error) {
	// Ignore SIGCHLD signal
	signal.Ignore(syscall.SIGCHLD)

	// Close STDOUT, STDIN, STDERR
	syscall.Close(0)
	syscall.Close(1)
	syscall.Close(2)

	// Become the process group leader
	syscall.Setsid()

	// // Clear umask
	syscall.Umask(022)

	// // chdir for root directory
	syscall.Chdir("/")

	// Notify that the child process started successfuly
	pipe := os.NewFile(uintptr(3), "pipe")
	if pipe != nil {
		defer pipe.Close()
		if err == nil {
			pipe.Write([]byte{DAEMONIZE_SUCCESS})
		} else {
			pipe.Write([]byte{DAEMONIZE_FAIL})
		}
	}
}
Beispiel #13
0
func (w *Watcher) readEvent() {
	var (
		buf   [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
		n     int                                     // Number of bytes read with read()
		errno error                                   // Syscall errno
	)

	for {

		select {
		case <-w.done:
			syscall.Close(w.fd)
			close(w.acceptEvent)
			close(w.Error)
			return
		default:
		}

		n, errno = syscall.Read(w.fd, buf[0:])

		if n == 0 {
			syscall.Close(w.fd)
			close(w.acceptEvent)
			close(w.Error)
			return
		}

		if n < syscall.SizeofInotifyEvent {
			log.Fatal("size of InotifyEvent error", errno)
		}

		var offset uint32 = 0

		for offset <= uint32(n-syscall.SizeofInotifyEvent) {
			raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
			event := new(FileEvent)
			event.wd = raw.Wd
			event.nameLen = raw.Len
			event.mask = raw.Mask
			event.cookie = raw.Cookie
			path := w.wm.paths[int(raw.Wd)]
			if raw.Len > 0 {
				// Point "bytes" at the first byte of the filename
				bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
				// The filename is padded with NUL bytes. TrimRight() gets rid of those.
				event.fileName = path + "/" + strings.TrimRight(string(bytes[0:raw.Len]), "\000")
			}

			if _, found := w.skipExt[filepath.Ext(event.fileName)]; !found {
				fmt.Println("--->", w.skipExt, "--->", filepath.Ext(event.fileName), "--->", found)
				//发送事件acceptEvent通道
				w.acceptEvent <- event
			} else {
				fmt.Println("过滤文件:", event.fileName)
			}

			offset += syscall.SizeofInotifyEvent + raw.Len
		}
	}
}
Beispiel #14
0
func (io *NetIOManager) ProxyNetAccept(serverinfo syscall.Sockaddr) (sa syscall.Sockaddr, err error) {
	var clientfd, serverfd int
	// accpet mongodb client connection request
	clientfd, clientinfo, err := syscall.Accept(io.proxy_server_fd)
	if err != nil {
		goto ClientError
	}

	err = syscall.SetNonblock(clientfd, true)
	if err != nil {
		goto ClientCleanup
	}

	err = syscall.EpollCtl(io.epoll_fd, syscall.EPOLL_CTL_ADD, clientfd,
		&syscall.EpollEvent{Events: syscall.EPOLLIN | syscall.EPOLLOUT |
			syscall.EPOLLRDHUP, Fd: int32(clientfd)})
	if err != nil {
		goto ClientCleanup
	}

	// establish connection with mongodb server
	serverfd, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM,
		syscall.IPPROTO_TCP)
	if err != nil {
		goto ServerError
	}

	err = syscall.Connect(serverfd, serverinfo)
	if err != nil {
		goto ServerCleanup
	}

	err = syscall.SetNonblock(serverfd, true)
	if err != nil {
		goto ServerCleanup
	}

	err = syscall.EpollCtl(io.epoll_fd, syscall.EPOLL_CTL_ADD, serverfd,
		&syscall.EpollEvent{Events: syscall.EPOLLIN | syscall.EPOLLOUT |
			syscall.EPOLLRDHUP, Fd: int32(serverfd)})
	if err != nil {
		goto ServerCleanup
	}

	// now proxy server becomes a bridge between client <-> server
	add_sock_peer(io, clientfd, clientinfo, serverfd, serverinfo)
	return clientinfo, nil

ServerCleanup:
	syscall.Close(serverfd)
ServerError:
	syscall.EpollCtl(io.epoll_fd, syscall.EPOLL_CTL_DEL, clientfd,
		&syscall.EpollEvent{Events: syscall.EPOLLIN | syscall.EPOLLOUT |
			syscall.EPOLLRDHUP, Fd: int32(clientfd)})
ClientCleanup:
	syscall.Close(clientfd)
ClientError:
	return nil, err
}
Beispiel #15
0
func initJob() {
	// Create Job object and assign current process to it.
	jobObject, err := createJobObject(nil, nil)
	if err != nil {
		log.Printf("CreateJobObject failed: %v", err)
		return
	}
	if err = assignProcessToJobObject(jobObject, currentProcess); err != nil {
		log.Printf("AssignProcessToJobObject failed: %v", err)
		syscall.Close(jobObject)
		return
	}
	iocp, err := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 1)
	if err != nil {
		log.Printf("CreateIoCompletionPort failed: %v", err)
		syscall.Close(jobObject)
		return
	}
	port := JOBOBJECT_ASSOCIATE_COMPLETION_PORT{
		CompletionKey:  uintptr(jobObject),
		CompletionPort: iocp,
	}
	err = setInformationJobObject(jobObject, JobObjectAssociateCompletionPortInformation, uintptr(unsafe.Pointer(&port)), uint32(unsafe.Sizeof(port)))
	if err != nil {
		log.Printf("SetInformationJobObject failed: %v", err)
		syscall.Close(jobObject)
		syscall.Close(iocp)
		return
	}
	// Read Job notifications about new "child" processes and collect them in childProcesses.
	go func() {
		var code, key uint32
		var o *syscall.Overlapped
		for {
			err := syscall.GetQueuedCompletionStatus(iocp, &code, &key, &o, syscall.INFINITE)
			if err != nil {
				log.Printf("GetQueuedCompletionStatus failed: %v", err)
				return
			}
			if key != uint32(jobObject) {
				panic("Invalid GetQueuedCompletionStatus key parameter")
			}
			if code == JOB_OBJECT_MSG_NEW_PROCESS {
				pid := int(uintptr(unsafe.Pointer(o)))
				if pid == syscall.Getpid() {
					continue
				}
				c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))
				if err != nil {
					log.Printf("OpenProcess failed: %v", err)
					continue
				}
				childMu.Lock()
				childProcesses = append(childProcesses, c)
				childMu.Unlock()
			}
		}
	}()
}
Beispiel #16
0
func traceOne(addr *syscall.SockaddrInet4, ttl int) *ReturnArgs {
	cli, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		exitWithError(err)
	}
	srv, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
	if err != nil {
		exitWithError(err)
	}

	defer syscall.Close(cli)
	defer syscall.Close(srv)

	// set ttl, stolen from somewhere else...
	// https://github.com/aeden/traceroute/blob/master/traceroute.go#L195
	if err := syscall.SetsockoptInt(cli, syscall.SOL_IP, syscall.IP_TTL, ttl); err != nil {
		exitWithError(err)
	}

	// set timeout, stolen from somewhere else...
	// https://github.com/aeden/traceroute/blob/master/traceroute.go#L197
	tv := syscall.NsecToTimeval(1e6 * TIMEOUT)
	if err := syscall.SetsockoptTimeval(srv, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv); err != nil {
		exitWithError(err)
	}
	if err := syscall.Bind(srv, toAddr(HOST, RECV_PORT)); err != nil {
		exitWithError(err)
	}

	rr := &ReturnArgs{}
	start := time.Now()
	if err := syscall.Sendto(cli, makeICMP(), 0, addr); err != nil {
		return rr
	}

	buf := make([]byte, 512)
	_, from, err := syscall.Recvfrom(srv, buf, 0)
	if err != nil {
		return rr
	}

	rr.elapsed = float64(time.Since(start).Nanoseconds()) / 1e6
	t, c := parseICMP(buf)
	if t == 3 && c == 3 { // Destination port unreachable, type==3 && code==3
		rr.done = true
	} else if t != 11 { // Time Exceeded, type==11 && code in (0,1)
		return rr
	}
	rr.ok = true
	rr.ip = toStr(from)
	addrs, err := net.LookupAddr(rr.ip)
	if err != nil {
		rr.addr = rr.ip
	} else {
		rr.addr = addrs[0]
	}
	return rr
}
Beispiel #17
0
func (constor *Constor) Write(input *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) {
	constor.log("%d", input.Fh)
	ptr := uintptr(input.Fh)
	offset := input.Offset

	F := constor.getfd(ptr)
	if F == nil {
		constor.error("F == nil")
		return 0, fuse.EIO
	}
	inode, err := constor.inodemap.findInode(input.NodeId)
	if err != nil {
		constor.error("%s", err)
		return 0, fuse.ToStatus(err)
	}
	if F.layer != 0 && inode.layer != 0 {
		err = constor.copyup(inode)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		path, err := constor.dentrymap.getPath(inode.ino)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		pathl := Path.Join(constor.layers[0], path)
		syscall.Close(F.fd)
		fd, err := syscall.Open(pathl, F.flags, 0)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		F.fd = fd
		F.layer = 0
		constor.log("reset fd for %s", path)
	} else if F.layer != 0 && inode.layer == 0 {
		syscall.Close(F.fd)
		path, err := constor.dentrymap.getPath(inode.ino)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		pathl := Path.Join(constor.layers[0] + path)
		fd, err := syscall.Open(pathl, F.flags, 0)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		F.fd = fd
		F.layer = 0
		constor.log("reset fd for %s", path)
	}

	fd := F.fd
	n, err := syscall.Pwrite(fd, data, int64(offset))
	return uint32(n), fuse.ToStatus(err)
}
Beispiel #18
0
Datei: trace.go Projekt: mag-/gtr
// Traceroute executes traceroute to given destination, using options from TracerouteOptions
// and sending updates to chan c
//
// Outbound packets are UDP packets and inbound packets are ICMP.
//
// Returns an error or nil if no error occurred
func Traceroute(dest *net.IPAddr, options *TracerouteOptions, c chan TraceUpdate) (err error) {
	var destAddr [4]byte
	copy(destAddr[:], dest.IP.To4())
	socketAddr, err := getSocketAddr()
	if err != nil {
		return
	}

	timeoutMs := (int64)(options.TimeoutMs)
	tv := syscall.NsecToTimeval(1000 * 1000 * timeoutMs)

	ttl := 1
	for {
		// Set up receiving socket
		recvSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
		if err != nil {
			log.Fatal("Cannot setup receive socket, please run as root or with CAP_NET_RAW permissions")
			return err
		}
		// Set up sending socket
		sendSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
		if err != nil {
			log.Fatal("Cannot setup sending socket")
			return err
		}

		start := time.Now()
		syscall.SetsockoptInt(sendSocket, 0x0, syscall.IP_TTL, ttl)
		syscall.SetsockoptTimeval(recvSocket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
		syscall.Bind(recvSocket, &syscall.SockaddrInet4{Port: options.Port, Addr: socketAddr})
		syscall.Sendto(sendSocket, []byte{0x0}, 0, &syscall.SockaddrInet4{Port: options.Port, Addr: destAddr})

		var p = make([]byte, options.PacketSize)
		n, from, err := syscall.Recvfrom(recvSocket, p, 0)
		elapsed := time.Since(start)
		if err == nil {
			currAddr := from.(*syscall.SockaddrInet4).Addr
			hop := TraceUpdate{Success: true, Address: currAddr, N: n, ElapsedTime: elapsed, TTL: ttl}
			currHost, err := net.LookupAddr(hop.addressString())
			if err == nil {
				hop.Host = currHost[0]
			}
			// Send update
			c <- hop
			ttl += 1
			// We reached the destination
			if ttl > options.MaxTTL || currAddr == destAddr {
				ttl = 1
			}
		} else {
			c <- TraceUpdate{Success: false, TTL: ttl}
			ttl += 1
		}
		syscall.Close(recvSocket)
		syscall.Close(sendSocket)
	}
}
Beispiel #19
0
// ListenPacket listens for incoming ICMP packets addressed to
// address. See net.Dial for the syntax of address.
//
// For non-privileged datagram-oriented ICMP endpoints, network must
// be "udp4" or "udp6". The endpoint allows to read, write a few
// limited ICMP messages such as echo request and echo reply.
// Currently only Darwin and Linux support this.
//
// Examples:
//	ListenPacket("udp4", "192.168.0.1")
//	ListenPacket("udp4", "0.0.0.0")
//	ListenPacket("udp6", "fe80::1%en0")
//	ListenPacket("udp6", "::")
//
// For privileged raw ICMP endpoints, network must be "ip4" or "ip6"
// followed by a colon and an ICMP protocol number or name.
//
// Examples:
//	ListenPacket("ip4:icmp", "192.168.0.1")
//	ListenPacket("ip4:1", "0.0.0.0")
//	ListenPacket("ip6:ipv6-icmp", "fe80::1%en0")
//	ListenPacket("ip6:58", "::")
func ListenPacket(network, address string) (*PacketConn, error) {
	var family, proto int
	switch network {
	case "udp4":
		family, proto = syscall.AF_INET, iana.ProtocolICMP
	case "udp6":
		family, proto = syscall.AF_INET6, iana.ProtocolIPv6ICMP
	default:
		i := last(network, ':')
		switch network[:i] {
		case "ip4":
			proto = iana.ProtocolICMP
		case "ip6":
			proto = iana.ProtocolIPv6ICMP
		}
	}
	var cerr error
	var c net.PacketConn
	switch family {
	case syscall.AF_INET, syscall.AF_INET6:
		s, err := syscall.Socket(family, syscall.SOCK_DGRAM, proto)
		if err != nil {
			return nil, os.NewSyscallError("socket", err)
		}
		if runtime.GOOS == "darwin" && family == syscall.AF_INET {
			if err := syscall.SetsockoptInt(s, iana.ProtocolIP, sysIP_STRIPHDR, 1); err != nil {
				syscall.Close(s)
				return nil, os.NewSyscallError("setsockopt", err)
			}
		}
		sa, err := sockaddr(family, address)
		if err != nil {
			syscall.Close(s)
			return nil, err
		}
		if err := syscall.Bind(s, sa); err != nil {
			syscall.Close(s)
			return nil, os.NewSyscallError("bind", err)
		}
		f := os.NewFile(uintptr(s), "datagram-oriented icmp")
		c, cerr = net.FilePacketConn(f)
		f.Close()
	default:
		c, cerr = net.ListenPacket(network, address)
	}
	if cerr != nil {
		return nil, cerr
	}
	switch proto {
	case iana.ProtocolICMP:
		return &PacketConn{c: c, p4: ipv4.NewPacketConn(c)}, nil
	case iana.ProtocolIPv6ICMP:
		return &PacketConn{c: c, p6: ipv6.NewPacketConn(c)}, nil
	default:
		return &PacketConn{c: c}, nil
	}
}
Beispiel #20
0
func mount(dir string, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) {
	// linux mount is never delayed
	close(ready)

	fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0)
	if err != nil {
		return nil, fmt.Errorf("socketpair error: %v", err)
	}
	defer syscall.Close(fds[0])
	defer syscall.Close(fds[1])

	cmd := exec.Command("fusermount", "--", dir)
	cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3")

	writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes")
	defer writeFile.Close()
	cmd.ExtraFiles = []*os.File{writeFile}

	out, err := cmd.CombinedOutput()
	if len(out) > 0 || err != nil {
		return nil, fmt.Errorf("fusermount: %q, %v", out, err)
	}

	readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
	defer readFile.Close()
	c, err := net.FileConn(readFile)
	if err != nil {
		return nil, fmt.Errorf("FileConn from fusermount socket: %v", err)
	}
	defer c.Close()

	uc, ok := c.(*net.UnixConn)
	if !ok {
		return nil, fmt.Errorf("unexpected FileConn type; expected UnixConn, got %T", c)
	}

	buf := make([]byte, 32) // expect 1 byte
	oob := make([]byte, 32) // expect 24 bytes
	_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
	if err != nil {
		return nil, fmt.Errorf("ParseSocketControlMessage: %v", err)
	}
	if len(scms) != 1 {
		return nil, fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms)
	}
	scm := scms[0]
	gotFds, err := syscall.ParseUnixRights(&scm)
	if err != nil {
		return nil, fmt.Errorf("syscall.ParseUnixRights: %v", err)
	}
	if len(gotFds) != 1 {
		return nil, fmt.Errorf("wanted 1 fd; got %#v", gotFds)
	}
	f := os.NewFile(uintptr(gotFds[0]), "/dev/fuse")
	return f, nil
}
func Stop() {
	logger.Log(logger.INFO, "Stop proxy server")
	if runTunnel != nil {
		syscall.Close(runTunnel.LFd)
		for _, tc := range fdTunnelConn {
			syscall.Close(tc.EFd)
			syscall.Close(tc.IFd)
		}
	}
}
Beispiel #22
0
func Hop(port, ttl int, IP_addr net.IP) (*Hop_ret, error) {

	ret_addr := net.IPv4(0, 0, 0, 0)
	success := false
	// make sockets
	send_udp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err != nil {
		return nil, err
	}
	recv_icmp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
	if err != nil {
		return nil, err
	}

	//editing TTL value for outgoing IPv4 packets
	if err := syscall.SetsockoptInt(send_udp_s, syscall.SOL_IP, syscall.IP_TTL, ttl); err != nil {
		return nil, err
	}
	tv := syscall.NsecToTimeval(1000 * 1000 * TIME_OUT_MS)
	syscall.SetsockoptTimeval(recv_icmp_s, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)

	defer syscall.Close(send_udp_s)
	defer syscall.Close(recv_icmp_s)

	//connect sockets
	if err := syscall.Bind(recv_icmp_s, &syscall.SockaddrInet4{Port: port, Addr: [4]byte{137, 224, 226, 47}}); err != nil {
		return nil, err
	}

	//send udp-packet
	var IP [4]byte
	copy(IP[:], IP_addr.To4())
	if err := syscall.Sendto(send_udp_s, []byte{0x42, 0x42}, 0, &syscall.SockaddrInet4{Port: 1337, Addr: IP}); err != nil {
		return nil, err
	}

	//receive ICMP
	recv_buffer := make([]byte, 4096)
	_, _, err = syscall.Recvfrom(recv_icmp_s, recv_buffer, 0)
	if err == nil {
		header, err := ipv4.ParseHeader(recv_buffer)
		if err != nil {
			log.Errorf("%q", err)
		}
		success = true
		ret_addr = header.Src
	} else {
		//time out
		success = false
		ret_addr = net.IPv4(0, 0, 0, 0)
		//log.Errorf("%q", err)
	}
	//resolve (timeout) errors, retry or return false...
	return &Hop_ret{Addr: ret_addr, TTL: ttl, success: success}, nil
}
Beispiel #23
0
// Listen returns TCP listener with SO_REUSEPORT option set.
//
// Only tcp4 network is supported.
//
// ErrNoReusePort error is returned if the system doesn't support SO_REUSEPORT.
func Listen(network, addr string) (l net.Listener, err error) {
	var (
		soType, fd int
		file       *os.File
		sockaddr   syscall.Sockaddr
	)

	if sockaddr, soType, err = getSockaddr(network, addr); err != nil {
		return nil, err
	}

	syscall.ForkLock.RLock()
	fd, err = syscall.Socket(soType, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
	if err == nil {
		syscall.CloseOnExec(fd)
	}
	syscall.ForkLock.RUnlock()
	if err != nil {
		return nil, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReusePort, 1); err != nil {
		syscall.Close(fd)
		return nil, &ErrNoReusePort{err}
	}

	if err = syscall.Bind(fd, sockaddr); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	name := fmt.Sprintf("reuseport.%d.%s.%s", os.Getpid(), network, addr)
	file = os.NewFile(uintptr(fd), name)
	if l, err = net.FileListener(file); err != nil {
		file.Close()
		return nil, err
	}

	if err = file.Close(); err != nil {
		l.Close()
		return nil, err
	}

	return l, err
}
Beispiel #24
0
func (self *AfAlg) Close() (e error) {
	err := syscall.Close(self.fd)
	if err != nil {
		e = err
	}
	syscall.Close(self.conn)
	if err != nil {
		e = err
	}
	return
}
Beispiel #25
0
func (gpio *GPIO) AddEdgeDetect(edge GPIOEdge) (chan bool, error) {
	gpio.RemoveEdgeDetect()

	err := gpio.SetDirection(GPIO_INPUT)
	if err != nil {
		return nil, err
	}
	err = gpio.SetEdge(edge)
	if err != nil {
		return nil, err
	}
	err = gpio.openValueFile()
	if err != nil {
		return nil, err
	}

	epfd, err := syscall.EpollCreate(1)
	if err != nil {
		return nil, err
	}

	event := &syscall.EpollEvent{
		Events: syscall.EPOLLIN | _EPOLLET | syscall.EPOLLPRI,
		Fd:     int32(gpio.value.Fd()),
	}
	err = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, int(gpio.value.Fd()), event)
	if err != nil {
		syscall.Close(epfd)
		return nil, err
	}

	// / first time triggers with current state, so ignore
	_, err = syscall.EpollWait(epfd, make([]syscall.EpollEvent, 1), -1)
	if err != nil {
		syscall.Close(epfd)
		return nil, err
	}

	gpio.epfd.Set(epfd)

	valueChan := make(chan bool)
	go func() {
		for gpio.epfd.Get() != 0 {
			n, _ := syscall.EpollWait(epfd, make([]syscall.EpollEvent, 1), -1)
			if n > 0 {
				value, err := gpio.Value()
				if err == nil {
					valueChan <- value
				}
			}
		}
	}()
	return valueChan, nil
}
Beispiel #26
0
// Close all poller file descriptors, but not the one passed to it.
func (poller *fdPoller) close() {
	if poller.pipe[1] != -1 {
		syscall.Close(poller.pipe[1])
	}
	if poller.pipe[0] != -1 {
		syscall.Close(poller.pipe[0])
	}
	if poller.epfd != -1 {
		syscall.Close(poller.epfd)
	}
}
Beispiel #27
0
// pivotRoot will call pivot_root such that rootfs becomes the new root
// filesystem, and everything else is cleaned up.
func pivotRoot(rootfs string) error {
	// While the documentation may claim otherwise, pivot_root(".", ".") is
	// actually valid. What this results in is / being the new root but
	// /proc/self/cwd being the old root. Since we can play around with the cwd
	// with pivot_root this allows us to pivot without creating directories in
	// the rootfs. Shout-outs to the LXC developers for giving us this idea.

	oldroot, err := syscall.Open("/", syscall.O_DIRECTORY|syscall.O_RDONLY, 0)
	if err != nil {
		return err
	}
	defer syscall.Close(oldroot)

	newroot, err := syscall.Open(rootfs, syscall.O_DIRECTORY|syscall.O_RDONLY, 0)
	if err != nil {
		return err
	}
	defer syscall.Close(newroot)

	// Change to the new root so that the pivot_root actually acts on it.
	if err := syscall.Fchdir(newroot); err != nil {
		return err
	}

	if err := syscall.PivotRoot(".", "."); err != nil {
		return fmt.Errorf("pivot_root %s", err)
	}

	// Currently our "." is oldroot (according to the current kernel code).
	// However, purely for safety, we will fchdir(oldroot) since there isn't
	// really any guarantee from the kernel what /proc/self/cwd will be after a
	// pivot_root(2).

	if err := syscall.Fchdir(oldroot); err != nil {
		return err
	}

	// Make oldroot rprivate to make sure our unmounts don't propagate to the
	// host (and thus bork the machine).
	if err := syscall.Mount("", ".", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
		return err
	}
	// Preform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
	if err := syscall.Unmount(".", syscall.MNT_DETACH); err != nil {
		return err
	}

	// Switch back to our shiny new root.
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	return nil
}
Beispiel #28
0
func (constor *Constor) Write(input *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) {
	constor.log("%d %d", input.Fh, len(data))
	ptr := uintptr(input.Fh)
	offset := input.Offset
	wdata := data

	F := constor.getfd(ptr)
	if F == nil {
		constor.error("F == nil")
		return 0, fuse.EIO
	}
	if F.flags&syscall.O_DIRECT != 0 {
		wdata = directio.AlignedBlock(len(data))
		copy(wdata, data)
	}
	inode := constor.inodemap.findInodePtr(input.NodeId)
	if inode == nil {
		return 0, fuse.ENOENT
	}
	if F.layer != 0 && inode.layer != 0 {
		err := constor.copyup(inode)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		path := constor.getPath(0, inode.id)
		syscall.Close(F.fd)
		fd, err := syscall.Open(path, F.flags, 0)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		F.fd = fd
		F.layer = 0
		constor.log("reset fd for %s", path)
	} else if F.layer != 0 && inode.layer == 0 {
		syscall.Close(F.fd)
		path := constor.getPath(0, inode.id)
		fd, err := syscall.Open(path, F.flags, 0)
		if err != nil {
			constor.error("%s", err)
			return 0, fuse.ToStatus(err)
		}
		F.fd = fd
		F.layer = 0
		constor.log("reset fd for %s", path)
	}

	fd := F.fd
	n, err := syscall.Pwrite(fd, wdata, int64(offset))
	return uint32(n), fuse.ToStatus(err)
}
Beispiel #29
0
func execinAction(container *libcontainer.Container, cmd *libcontainer.Command, fds []uintptr) error {
	for _, fd := range fds {
		if fd > 0 {
			if err := JoinExistingNamespace(fd, ""); err != nil {
				for _, fd := range fds {
					syscall.Close(int(fd))
				}
				return err
			}
		}
		syscall.Close(int(fd))
	}

	if container.Namespaces.Contains(libcontainer.CLONE_NEWNS) &&
		container.Namespaces.Contains(libcontainer.CLONE_NEWPID) {
		// important:
		// we need to fork and unshare so that re can remount proc and sys within
		// the namespace so the CLONE_NEWPID namespace will take effect
		// if we don't fork we would end up unmounting proc and sys for the entire
		// namespace
		child, err := fork()
		if err != nil {
			return fmt.Errorf("fork child %s", err)
		}

		if child == 0 {
			if err := unshare(CLONE_NEWNS); err != nil {
				writeError("unshare newns %s", err)
			}
			if err := remountProc(); err != nil {
				writeError("remount proc %s", err)
			}
			if err := remountSys(); err != nil {
				writeError("remount sys %s", err)
			}
			if err := capabilities.DropCapabilities(container); err != nil {
				writeError("drop caps %s", err)
			}

			if err := exec(cmd.Args[0], cmd.Args[0:], cmd.Env); err != nil {
				writeError("exec %s", err)
			}
			// unreachable
		}
		exit, err := utils.WaitOnPid(child)
		if err != nil {
			writeError("wait on child %s", err)
		}
		os.Exit(exit)
	}
	return nil
}
Beispiel #30
0
// Generic socket creation.
func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) {
	// See ../syscall/exec.go for description of ForkLock.
	syscall.ForkLock.RLock()
	s, e := syscall.Socket(f, p, t)
	if e != 0 {
		syscall.ForkLock.RUnlock()
		return nil, os.Errno(e)
	}
	syscall.CloseOnExec(s)
	syscall.ForkLock.RUnlock()

	// Allow reuse of recently-used addresses.
	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)

	// Allow broadcast.
	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)

	if f == syscall.AF_INET6 {
		// using ip, tcp, udp, etc.
		// allow both protocols even if the OS default is otherwise.
		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, 0)
	}

	if la != nil {
		e = syscall.Bind(s, la)
		if e != 0 {
			syscall.Close(s)
			return nil, os.Errno(e)
		}
	}

	if ra != nil {
		e = syscall.Connect(s, ra)
		if e != 0 {
			syscall.Close(s)
			return nil, os.Errno(e)
		}
	}

	sa, _ := syscall.Getsockname(s)
	laddr := toAddr(sa)
	sa, _ = syscall.Getpeername(s)
	raddr := toAddr(sa)

	fd, err = newFD(s, f, p, net, laddr, raddr)
	if err != nil {
		syscall.Close(s)
		return nil, err
	}

	return fd, nil
}