Example #1
0
//FindAll finds the MTU for each connection specified in the
//configuration. Use Find() if you're only looking for a specific MTU.
func FindAll() {
	if !initalized {
		log.Println("Please make sure that the MTU package was configured with mtu.Init(.., ..)")
		return
	}
	c := conf
	//Setup a mtuOK channel for each config
	var mtuOkChannels = make(map[int]chan int)
	for conf := range c.MTUConfList {
		mtuOkChannels[conf] = make(chan int, 100)
	}

	var quitDistribute = make(chan bool)
	go distributeMtuOkPackets(icmpPacketsStage2, mtuOkChannels, quitDistribute)

	var wg sync.WaitGroup
	for conf := range c.MTUConfList {
		logging.InfoLog("Starting MTU Discovery " + strconv.Itoa(conf+1) + "/" + strconv.Itoa(len(c.MTUConfList)) +
			" between " + c.MTUConfList[conf].SourceIP + " and " + c.MTUConfList[conf].DestinationIP + ". Reported by AppID " + strconv.Itoa(c.ApplicationID) + ".")
		wg.Add(1)
		go find(
			c.MTUConfList[conf],
			c.ApplicationID,
			conf,
			mtuOkChannels[conf],
			&wg)
	}

	//Wait until all MTU's have been detected
	wg.Wait()
	quitDistribute <- true
}
Example #2
0
//find finds the ideal MTU between two nodes by sending batches of packets with varying sizes
//to a remote node. The remote nodes is requires to respond to those packets if it received them.
//so it can determine the largest packet that was received on the remote node and the smallest packet that
//went missing. In a next step FastMTU sends again a batch of packets with sizes between the largest successful
//and smallest unsuccessful packet. This behaviour is continued until the size-difference between individual
//packets is no larger then 1Byte. Once that happens the largest successful packet is reported as MTU.
func find(mtuConf config.MTUConfig, appID int, chanID int, mtuOK chan int, wg *sync.WaitGroup) int {
	if !initalized {
		log.Println("Please make sure that the MTU package was configured with mtu.Init(.., ..)")
		return 0
	}
	var rangeStart = mtuConf.MTURangeStart
	var rangeEnd = mtuConf.MTURangeEnd
	var itStep = ((rangeEnd - rangeStart) / mtuConf.ConcurrentPackets)
	var roughMTU = 0
	var mtuDetected = false
	var retries = 0

	for !mtuDetected {
		if itStep == 0 {
			itStep = 1
			mtuDetected = true
		}
		roughMTU = sendBatch(mtuConf.SourceIP, mtuConf.DestinationIP, rangeStart, rangeEnd, itStep, mtuConf.Timeout, appID, chanID, mtuOK)

		if roughMTU == rangeEnd {
			//If all packets are successful there's a chance that our range is too small. This could be because of packet loss
			//in a earlier iteration or because the range in the configuration was chosen too small. So we double the
			//range and reset mtuDetected to make sure it runs once more. We also recalculate the itStep to prevent
			//a packet flood if the range is suddenly big and we had a small itstep before.
			mtuDetected = false
			rangeStart = rangeEnd
			rangeEnd = 2 * rangeEnd
			itStep = ((rangeEnd - rangeStart) / mtuConf.ConcurrentPackets)
		} else if roughMTU == 0 {
			//If no packet is successful we run 1 retry.
			if retries < 1 {
				retries++
				log.Println("ERROR: Reported 0.. trying again.")
			} else {
				log.Println("ERROR: Reported MTU 0.. ")
				mtuDetected = true
			}
		} else {
			//This is the normal case. We had some successful and some unsuccessful packets. The range is set between
			//the last successful and the first unsuccessful packet. Then the itStep is recalculated.
			rangeStart = roughMTU
			rangeEnd = roughMTU + itStep
			itStep = ((rangeEnd - rangeStart) / mtuConf.ConcurrentPackets)
		}
	}
	report := "MTU between " + mtuConf.SourceIP + " and " + mtuConf.DestinationIP + " is " + strconv.Itoa(roughMTU) + ". Reported by AppID " + strconv.Itoa(conf.ApplicationID) + "."
	logging.InfoLog(report)
	wg.Done()
	return roughMTU
}