Example #1
0
func epmdC(n *Node, resp chan uint16) {
	conn, err := net.Dial("tcp", ":4369")
	if err != nil {
		resp <- 100
		return
	}
	defer conn.Close()

	epmdFROM := make(chan []byte)
	go epmdREADER(conn, epmdFROM)

	epmdTO := make(chan []byte)
	go epmdWRITER(conn, epmdFROM, epmdTO)

	epmdTO <- epmd.Compose_ALIVE2_REQ(&n.NodeInfo)

	for {

		select {
		case reply := <-epmdFROM:
			nLog("From EPMD: %v", reply)

			switch epmd.MessageId(reply[0]) {
			case epmd.ALIVE2_RESP:
				if creation, ok := epmd.Read_ALIVE2_RESP(reply); ok {
					resp <- creation
				} else {
					resp <- 99
				}
			}

		}

	}
}
Example #2
0
func epmReg(in <-chan regReq) {
	var nReg = make(map[string]*nodeRec)
	for {
		select {
		case req := <-in:
			buf := req.buf
			if len(buf) == 0 {
				rs := len(nReg)
				log.Printf("REG %d records", rs)
				now := time.Now()

				for node, rec := range nReg {
					if rec.conn == req.conn {
						log.Printf("Connection for %s dropped", node)
						nReg[node].Active = false
						nReg[node].Time = now
						nReg[node].conn = nil
					} else if rs > regLimit && !rec.Active && now.Sub(rec.Time).Minutes() > float64(unregTTL) {
						log.Printf("REG prune %s:%+v", node, rec)
						delete(nReg, node)
					}
				}
				continue
			}
			replyTo := req.replyTo
			log.Printf("IN: %v", buf)
			switch epmd.MessageId(buf[0]) {
			case epmd.ALIVE2_REQ:
				nConn := req.conn
				nInfo := epmd.Read_ALIVE2_REQ(buf)
				log.Printf("NodeInfo: %+v", nInfo)
				var reply []byte

				if rec, ok := nReg[nInfo.Name]; ok {
					log.Printf("Node %s found", nInfo.Name)
					if rec.Active {
						log.Printf("Node %s is running", nInfo.Name)
						reply = epmd.Compose_ALIVE2_RESP(false)
					} else {
						log.Printf("Node %s is not running", nInfo.Name)
						rec.conn = nConn

						nInfo.Creation = (rec.Creation % 3) + 1
						rec.NodeInfo = nInfo
						rec.Active = true
						reply = epmd.Compose_ALIVE2_RESP(true, rec.NodeInfo)
					}
				} else {
					log.Printf("New node %s", nInfo.Name)
					nInfo.Creation = 1
					rec := &nodeRec{
						NodeInfo: nInfo,
						conn:     nConn,
						Time:     time.Now(),
						Active:   true,
					}
					nReg[nInfo.Name] = rec
					reply = epmd.Compose_ALIVE2_RESP(true, rec.NodeInfo)
				}
				replyTo <- regAns{reply: reply, isClose: false}
			case epmd.PORT_PLEASE2_REQ:
				nName := epmd.Read_PORT_PLEASE2_REQ(buf)
				var reply []byte
				if rec, ok := nReg[nName]; ok && rec.Active {
					reply = epmd.Compose_PORT2_RESP(rec.NodeInfo)
				} else {
					reply = epmd.Compose_PORT2_RESP(nil)
				}
				replyTo <- regAns{reply: reply, isClose: true}
			case epmd.STOP_REQ:
				nName := epmd.Read_STOP_REQ(buf)
				var reply []byte
				if rec, ok := nReg[nName]; ok && rec.Active {
					// TODO: stop node
					reply = epmd.Compose_STOP_RESP(true)
				} else {
					reply = epmd.Compose_STOP_RESP(false)
				}
				replyTo <- regAns{reply: reply, isClose: true}
			case epmd.NAMES_REQ, epmd.DUMP_REQ:
				lp, err := strconv.Atoi(listenPort)
				if err != nil {
					log.Printf("Cannot convert %s to integer", listenPort)
					replyTo <- regAns{reply: nil, isClose: true}
				} else {
					replyB := new(bytes.Buffer)
					epmd.Compose_START_NAMES_RESP(replyB, lp)
					for _, rec := range nReg {
						if epmd.MessageId(buf[0]) == epmd.NAMES_REQ {
							if rec.Active {
								epmd.Append_NAMES_RESP(replyB, rec.NodeInfo)
							} else {
								if rec.Active {
									epmd.Append_DUMP_RESP_ACTIVE(replyB, rec.NodeInfo)
								} else {
									epmd.Append_DUMP_RESP_UNUSED(replyB, rec.NodeInfo)
								}
							}
						}
					}
					replyTo <- regAns{reply: replyB.Bytes(), isClose: true}
				}
			case epmd.KILL_REQ:
				reply := epmd.Compose_KILL_RESP()
				replyTo <- regAns{reply: reply, isClose: true}
			default:
				switch cliMessageId(buf[0]) {
				case REQ_NAMES:
					reply := ansNames(nReg)
					replyTo <- regAns{reply: reply, isClose: true}
				default:
					replyTo <- regAns{reply: nil, isClose: true}
				}
			}
		}
	}
}