Example #1
0
func main() {
	var (
		rset, wset, eset            syscall.FdSet
		still_running, curl_timeout int = 0, 0
		err                         error
	)

	ch1 := curl.EasyInit()
	ch2 := curl.EasyInit()

	ch1.Setopt(curl.OPT_URL, "http://www.163.com")
	ch1.Setopt(curl.OPT_HEADER, 0)
	ch1.Setopt(curl.OPT_VERBOSE, true)
	ch2.Setopt(curl.OPT_URL, "http://www.baidu.com")
	ch2.Setopt(curl.OPT_HEADER, 0)
	ch2.Setopt(curl.OPT_VERBOSE, true)

	mh := curl.MultiInit()

	mh.AddHandle(ch1)
	mh.AddHandle(ch2)

	for {
		FD_ZERO(&rset)
		FD_ZERO(&wset)
		FD_ZERO(&eset)

		timeout := syscall.Timeval{Sec: 1, Usec: 0}
		curl_timeout, err = mh.Timeout()
		if err != nil {
			fmt.Printf("Error multi_timeout: %s\n", err)
		}
		if curl_timeout >= 0 {
			timeout.Sec = int64(curl_timeout / 1000)
			if timeout.Sec > 1 {
				timeout.Sec = 1
			} else {
				timeout.Usec = int64((curl_timeout % 1000)) * 1000
			}
		}

		max_fd, err := mh.Fdset(&rset, &wset, &eset)
		if err != nil {
			fmt.Printf("Error FDSET: %s\n", err)
		}

		_, err = syscall.Select(int(max_fd+1), &rset, &wset, &eset, &timeout)
		if err != nil {
			fmt.Printf("Error select: %s\n", err)
		} else {
			still_running, err = mh.Perform()
			if still_running > 0 {
				fmt.Printf("Still running: %d\n", still_running)
			} else {
				break
			}
		}
	}

}
Example #2
0
func (w *Worker) createRawSocket() (fd int) {

	socket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_TCP)
	if err != nil {

		fmt.Fprintf(os.Stderr, "fail to Socket :%s\n", err.Error())
		os.Exit(1)
	}

	err = syscall.SetsockoptString(socket, syscall.IPPROTO_IP, syscall.IP_HDRINCL, "1")
	if err != nil {
		fmt.Fprintf(os.Stderr, "SetsockoptString error :%s\ns", err.Error())
		os.Exit(1)
	}

	timeVal := new(syscall.Timeval)
	timeVal.Sec = 6
	err = syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, timeVal)
	if err != nil {
		fmt.Fprintf(os.Stderr, "SetsockoptTimeval error :%s", err.Error())
		os.Exit(1)
	}

	return socket
}
Example #3
0
func (self *Uptime) Get() error {
	tv := syscall.Timeval{}

	if err := sysctlbyname("kern.boottime", &tv); err != nil {
		return err
	}

	self.Length = time.Since(time.Unix(tv.Unix())).Seconds()

	return nil
}
Example #4
0
func getRusage(usage usageType) float64 {
	rusage := &syscall.Rusage{}
	syscall.Getrusage(0, rusage)
	var time *syscall.Timeval
	if usage == USER_TIME {
		time = &rusage.Utime
	} else {
		time = &rusage.Stime
	}
	nsec := time.Nano()
	return float64(nsec) / 1000000000
}
Example #5
0
func (p *Pinger) listenIpv4() {
	if p.conn == nil {
		panic("conn doesnt exist")
	}
	log.Printf("starting rawSocket listener\n")
	rb := make([]byte, 1500)
	pkt := EchoResponse{}
	var readErr error
	var data []byte
	ipconn, ok := p.conn.(*net.IPConn)
	if !ok {
		panic("connection is not IPConn")
	}
	file, err := ipconn.File()
	if err != nil {
		panic(err.Error())
	}
	defer file.Close()
	fd := file.Fd()

	var pktTime time.Time
	recvTime := syscall.Timeval{}
	for {
		if p.conn == nil {
			break
		}
		n, peer, err := p.conn.ReadFrom(rb)
		if err != nil {
			readErr = err
			break
		}
		_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.SIOCGSTAMP), uintptr(unsafe.Pointer(&recvTime)))
		err = nil
		if errno != 0 {
			err = errno
		}
		if err == nil {
			pktTime = time.Unix(0, recvTime.Nano())
		} else {
			pktTime = time.Now()
		}

		rm, err := icmp.ParseMessage(ProtocolICMP, rb[:n])
		if err != nil {
			fmt.Println(err.Error())
			continue
		}
		if rm.Type == ipv4.ICMPTypeEchoReply {
			data = rm.Body.(*icmp.Echo).Data
			if len(data) < 9 {
				log.Printf("go-pinger: invalid data payload from %s. Expected at least 9bytes got %d", peer.String(), len(data))
				continue
			}
			pkt = EchoResponse{
				Peer:     peer.String(),
				Seq:      rm.Body.(*icmp.Echo).Seq,
				Id:       rm.Body.(*icmp.Echo).ID,
				Received: pktTime,
			}
			if p.Debug {
				log.Printf("go-pinger: recieved pkt. %s\n", pkt.String())
			}
			select {
			case p.packetChan <- pkt:
			default:
				log.Printf("go-pinger: droped echo response due to blocked packetChan. %s\n", pkt.String())
			}
		}
	}
	if p.Debug {
		log.Printf("listen loop ended.")
	}
	p.m.Lock()
	if p.running {
		log.Println(readErr.Error())
		p.Stop()
		p.start()
	}
	p.m.Unlock()
}
Example #6
0
// timeToTimeval - Convert time.Time to syscall.Timeval
//
// Note: This does not use syscall.NsecToTimespec because
// that does not work properly for times before 1970,
// see https://github.com/golang/go/issues/12777
func timeToTimeval(t *time.Time) syscall.Timeval {
	var tv syscall.Timeval
	tv.Usec = int32(t.Nanosecond() / 1000)
	tv.Sec = t.Unix()
	return tv
}
Example #7
0
func timevalToDuration(tv syscall.Timeval) time.Duration {
	return time.Duration(tv.Nano()) * time.Nanosecond
}
Example #8
0
// Returns errors (if any) triggered by the inotify subsystem or when reading
// the file. Errors when writing to the writer are ignored.
func streamFile(writer io.Writer, path string, maxIdleTime uint32) error {
	handle, err := os.Open(path)
	if err != nil {
		return err
	}

	_, err = handle.Seek(0, os.SEEK_END)
	if err != nil {
		handle.Close()
		return err
	}

	reader := bufio.NewReader(handle)
	readBuffer := make([]byte, 4096)

	inotifyFd, err := syscall.InotifyInit()
	if err != nil {
		handle.Close()
		return err
	}

	watchDesc, err := syscall.InotifyAddWatch(inotifyFd, path,
		syscall.IN_MODIFY)
	if err != nil {
		syscall.Close(inotifyFd)
		handle.Close()
		return err
	}

	eventsBuffer := make([]byte, syscall.SizeofInotifyEvent*4096)

	selectMaxIdleTime := syscall.Timeval{}
	selectMaxIdleTime.Sec = int64(maxIdleTime)

	inotifyFdSet := syscall.FdSet{}
	lastWriteTime := time.Now()

	canScan := true
	for canScan && !timeout(lastWriteTime, maxIdleTime) {
		clearAll(&inotifyFdSet)
		set(&inotifyFdSet, inotifyFd)
		_, err := syscall.Select(inotifyFd+1, &inotifyFdSet,
			nil, nil, &selectMaxIdleTime)

		if err != nil {
			break
		}

		if !isSet(&inotifyFdSet, inotifyFd) {
			continue
		}

		numEventsBytes, err := syscall.Read(inotifyFd, eventsBuffer[0:])
		if numEventsBytes < syscall.SizeofInotifyEvent {
			if numEventsBytes < 0 {
				err = errors.New("inotify: read failed.")
			} else {
				err = errors.New("inotify: short read.")
			}

			break
		}

		var offset uint32 = 0
		for offset <= uint32(numEventsBytes-syscall.SizeofInotifyEvent) {
			event := (*syscall.InotifyEvent)(unsafe.
				Pointer(&eventsBuffer[offset]))

			n, err := reader.Read(readBuffer)
			if err != nil {
				// Ignore the EOF error and continue polling
				// the file until timeout.
				if err == io.EOF {
					err = nil
				}
				break
			}

			buffer := make([]byte, n)
			for index := 0; index < n; index++ {
				buffer[index] = readBuffer[index]
			}

			_, err = writer.Write(buffer)
			if err != nil {
				// Stop scanning for updates to the file.
				canScan = false
				// Ignore the write error.
				err = nil
				break
			}

			lastWriteTime = time.Now()
			// Move to the next event.
			offset += syscall.SizeofInotifyEvent + event.Len
		}
	}

	// The inotify watch gets automatically removed by the inotify system
	// when the file is removed. If the above loop times out, but the file
	// is removed only just before the if block below is executed, then the
	// removal of the watch below will throw an error as the watch
	// descriptor is obsolete. We ignore this error because it is harmless.
	syscall.InotifyRmWatch(inotifyFd, uint32(watchDesc))

	// Though we return the first error that occured, we still need to
	// attempt to close all the file descriptors.
	inotifyCloseErr := syscall.Close(inotifyFd)
	handleCloseErr := handle.Close()

	if err != nil {
		return err
	} else if inotifyCloseErr != nil {
		return inotifyCloseErr
	}

	return handleCloseErr
}
Example #9
0
func (s *SyncReceiver) HandleConnection(conn net.Conn) {
	var err error
	defer func() {
		log.Println("Receiver: client disconnect with:", err)
		if err != nil {
			conn.Write([]byte{VerifyResultError})
		}
		conn.Close()
	}()

	log.Println("New Connection Com")
	br := bufio.NewReader(conn)
	headerLen := syncHeaderLen()
	headerBuf := make([]byte, headerLen)
	_, err = br.Read(headerBuf)
	if err != nil {
		return
	}

	syncHeader := NewSyncHeaderFromBytes(headerBuf)

	log.Println("Read Header Succ", syncHeader.FileLength)

	buf_filename, err := br.ReadBytes('\n')
	//log.Println(len(buf_filename), buf_filename)
	if len(buf_filename) <= 1 {
		return
	}
	filename := string(buf_filename[0 : len(buf_filename)-1])
	log.Println("filename:", filename)
	filename = path.Join(s.cfg.SyncRootFolder, filename)
	var fi os.FileInfo
	fi, err = os.Stat(filename)
	if os.IsNotExist(err) || fi.IsDir() {
		log.Printf("no such file: %s\n", filename)
		conn.Write([]byte{VerifyResultTransferToMe})
		//NOW Read&Write Entire File

		rbuf := make([]byte, 512) //readbuf
		//create temp file
		tempfilename := filename + ".syncing"
		tempFile, err := os.Create(tempfilename)
		if err != nil {
			log.Println("Create temp file error", err)
			return
		}

		endTransfer := false
		readedBytes := int64(0)
		for !endTransfer {
			n, err := br.Read(rbuf)
			if err != nil {
				log.Println("Transfering File Err:", err)
				return
			}
			if n > 0 {
				if nw, err := tempFile.Write(rbuf[0:n]); err != nil || nw != n {
					log.Println("Write tempfile error")
					return
				}
			}
			readedBytes += int64(n)
			if readedBytes > syncHeader.FileLength {
				log.Println("Transfer more than syncheader:", readedBytes, syncHeader.FileLength)
				return
			} else if readedBytes == syncHeader.FileLength {
				endTransfer = true
			}
			log.Println("recv:", n)
		}
		if err := tempFile.Close(); err != nil {
			log.Println("Sync&Close temp file failed!")
			return
		} //
		log.Println("file recv over")
		//rename file & give a new mod time
		os.Rename(tempfilename, filename)
		fi, _ = os.Stat(filename)
		accessTimeval := new(syscall.Timeval)
		accessTimeval.Sec = fi.ModTime().Unix()
		modTimeval := new(syscall.Timeval)
		modTimeval.Sec = syncHeader.FileModTime.Unix()
		err = syscall.Utimes(filename, []syscall.Timeval{*accessTimeval, *modTimeval})
		if err != nil {
			log.Println("utime error:", err)
			return
		}
		err = nil
		conn.Write([]byte{VerifyResultDoNext})
		log.Println("sync over!!!")
	} else {
		if syncHeader.FileLength == fi.Size() && syncHeader.FileModTime.Equal(fi.ModTime()) {
			log.Println("Timestamp & Size Equal. This file is synced")
			conn.Write([]byte{VerifyResultDoNext})
			//TBD continue the loop
		} else {
			log.Println("Modtime not equal. So need file compare")
			//Send need compare flag
			conn.Write([]byte{VerifyResultNeedCompare})
			//Compute & Send chunkchecksum
			// syncHeader.FileLength

			f, err := os.Open(filename)
			if err != nil {
				log.Println("open file err:", err)
				return
			}
			checkSum := NewRollingCheckSum(f, syncHeader.ChunkSize)
			hashes, err := checkSum.SumEveryChunk()
			if err != nil {
				log.Println("error when generate checksum", err)
				return
			}

			checksumBytes := CheckSumPackArrayToBytes(hashes)
			conn.Write(checksumBytes)

			//adler+md5
			//Recv TransferData Packages
		}
	}

	/*
		version := br.ReadByte()
		packageType  := br.ReadByte()
		if !(version == 0x01 && packageType == PackageTypeSyncRequest) {

			return
		}
		return
		temp2 := make([]byte, 2)
		br.Read(temp)
		//little endian
		packageLen := uint16(temp2[0])|(uint16(temp2[1])<<8)

		io.WriteString(conn, "Hi")
	*/
}