func (s *Server) fillStaticHeaders(response *ntp.Packet) {
	response.Stratum = uint8(s.Stratum)
	response.Precision = -32
	response.RootDelay = 0
	response.RootDispersion = 10
	response.ReferenceID = binary.BigEndian.Uint32([]byte(fmt.Sprintf("%-4s", s.RefID)))
}
fillStaticHeaders pre-sets all the headers per worker which will never change
numbers are taken from tcpdump.
package server
import (
	"context"
	"encoding/binary"
	"fmt"
	"net"
	"time"
	"github.com/facebookincubator/ntp/protocol/ntp"
	log "github.com/sirupsen/logrus"
)
type task struct {
	conn     net.PacketConn
	addr     net.Addr
	received time.Time
	request  *ntp.Packet
	stats    Stats
}
type Server struct {
	ListenConfig ListenConfig
	Workers      int
	Announce     Announce
	Stats        Stats
	Checker      Checker
	tasks        chan task
	ExtraOffset  time.Duration
	RefID        string
	Stratum      int
}
func (s *Server) Start(ctx context.Context, cancelFunc context.CancelFunc) {
	log.Infof("Creating %d goroutine workers", s.Workers)
	s.tasks = make(chan task, s.Workers)
	for i := 0; i < s.Workers; i++ {
		go s.startWorker()
	}
	log.Infof("Starting %d listener(s)", len(s.ListenConfig.IPs))
	for _, ip := range s.ListenConfig.IPs {
		log.Infof("Starting listener on %s:%d", ip.String(), s.ListenConfig.Port)
		go func(ip net.IP) {
			s.Stats.IncListeners()
			if err := s.addIPToInterface(ip); err != nil {
				log.Errorf("[server]: %v", err)
			}
			s.startListener(ip, s.ListenConfig.Port)
			s.Stats.DecListeners()
		}(ip)
	}
	go func() {
		for {
			time.Sleep(time.Minute)
			log.Debug("[Checker] running internal health checks")
			err := s.Checker.Check()
			if err != nil {
				log.Errorf("[Checker] internal error: %v", err)
				cancelFunc()
				return
			}
		}
	}()
	for {
		select {
		case <-ctx.Done():
			break
		case <-time.After(30 * time.Second):
			if s.ListenConfig.ShouldAnnounce {
				log.Debug("Requesting VIPs announce")
				err := s.Announce.Advertise(s.ListenConfig.IPs)
				if err != nil {
					log.Errorf("Error during announcement: %v", err)
					s.Stats.ResetAnnounce()
				} else {
					s.Stats.SetAnnounce()
				}
			} else {
				s.Stats.ResetAnnounce()
			}
		}
	}
}
func (s *Server) Stop() {
	if err := s.Announce.Withdraw(); err != nil {
		log.Errorf("[server] failed to withdraw announce: %v", err)
	}
	s.DeleteAllIPs()
}
func (s *Server) startListener(ip net.IP, port int) {
	s.Checker.IncListeners()
	defer s.Checker.DecListeners()
	conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: ip, Port: port})
	if err != nil {
		log.Fatalf("listening error: %s", err)
	}
	defer conn.Close()
	if err := ntp.EnableKernelTimestampsSocket(conn); err != nil {
		log.Fatalf("enabling timestamp error: %s", err)
	}
	for {
		request, nowKernelTimestamp, returnaddr, err := ntp.ReadPacketWithKernelTimestamp(conn)
		if err != nil {
			log.Errorf("read packet with timestamp error: %s", err)
			s.Stats.IncReadError()
			continue
		}
		s.Stats.IncRequests()
		s.tasks <- task{conn: conn, addr: returnaddr, received: nowKernelTimestamp, request: request, stats: s.Stats}
	}
}
func (s *Server) startWorker() {
	s.Checker.IncWorkers()
	defer s.Checker.DecWorkers()
	defer s.Stats.DecWorkers()
	response := &ntp.Packet{}
	s.fillStaticHeaders(response)
	s.Stats.IncWorkers()
	for {
		task := <-s.tasks
		task.serve(response, s.ExtraOffset)
	}
}
func (t *task) serve(response *ntp.Packet, extraoffset time.Duration) {
	log.Debugf("Received request: %+v", t.request)
	if t.request.ValidSettingsFormat() {
		generateResponse(time.Now().Add(extraoffset), t.received.Add(extraoffset), t.request, response)
		responseBytes, err := response.Bytes()
		if err != nil {
			log.Errorf("Failed to convert ntp.%v to bytes %v: %v", response, responseBytes, err)
			return
		}
		log.Debugf("Writing from: %v", t.conn.LocalAddr())
		log.Debugf("Writing response: %+v", response)
		_, err = t.conn.WriteTo(responseBytes, t.addr)
		if err != nil {
			log.Debugf("Failed to respond to the request: %v", err)
		}
		t.stats.IncResponses()
		return
	}
	log.Debugf("Invalid query, discarding: %v", t.request)
	t.stats.IncInvalidFormat()
}