Esempio n. 1
0
func (rpcs *rpcRex) HandleCall(message *etf.Term, from *etf.Tuple) (reply *etf.Term) {
	nLog("REX: HandleCall: %#v, From: %#v", *message, *from)
	var replyTerm etf.Term
	valid := false
	switch req := (*message).(type) {
	case etf.Tuple:
		if len(req) > 0 {
			switch act := req[0].(type) {
			case etf.Atom:
				if string(act) == "call" {
					valid = true
					if fun, ok := rpcs.callMap[modFun{string(req[1].(etf.Atom)), string(req[2].(etf.Atom))}]; ok {
						replyTerm = fun(req[3].(etf.List))
					} else {
						replyTerm = etf.Term(etf.Tuple{etf.Atom("badrpc"), etf.Tuple{etf.Atom("EXIT"), etf.Tuple{etf.Atom("undef"), etf.List{etf.Tuple{req[1], req[2], req[3], etf.List{}}}}}})
					}
				}
			}
		}
	}
	if !valid {
		replyTerm = etf.Term(etf.Tuple{etf.Atom("badrpc"), etf.Atom("unknown")})
	}
	reply = &replyTerm
	return
}
Esempio n. 2
0
// shutdown request
// takes no arguments
func (r *Relay) rpcShutdown(terms etf.List) etf.Term {
	if len(terms) != 0 {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarith")})
	}
	r.shutdown()
	r.shutdownChan <- struct{}{}
	return etf.Term(etf.Atom("ok"))
}
Esempio n. 3
0
// rpc funcs for erlang nodes
// args must be in form `[Name:string]`
// returns either `ok` or `{error, Reason}`
func (r *Relay) rpcCreateFS(terms etf.List) etf.Term {
	if len(terms) != 1 {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarith")})
	}
	t := terms[0]
	if _, ok := t.(string); !ok {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarg")})
	}
	name := t.(string)
	err := r.createFS(name)
	if err != nil {
		println("cannot create fs: ", err)
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("failed-to-create-fs")})
	}
	return etf.Term(etf.Atom("ok"))
}
Esempio n. 4
0
// HandleCall handles incoming messages from `gen_server:call/2`, if returns non-nil term,
// then calling process have reply
// Call `gen_server:call({go_srv, gonode@localhost}, Message)` at Erlang node
func (gs *gonodeSrv) HandleCall(message *etf.Term, from *etf.Tuple) (reply *etf.Term) {
	log.Printf("GO_SRV: HandleCall: %#v, From: %#v", *message, *from)

	// Just create new term tuple where first element is atom 'ok', second 'go_reply' and third is original message
	replyTerm := etf.Term(etf.Tuple{etf.Atom("ok"), etf.Atom("go_reply"), *message})
	reply = &replyTerm
	return
}
Esempio n. 5
0
// args must be in form `[FSName:string, DevName:string, isSensor/optional,
//    isAffector/optional]
// return `{ok, Pid}` or `{error, Reason}`
func (r *Relay) rpcCreateDevice(terms etf.List) etf.Term {
	if len(terms) != 3 {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarith")})
	}
	tFSName := terms[0]
	if _, ok := tFSName.(string); !ok {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarg")})
	}
	fsName := tFSName.(string)
	tDeviceName := terms[1]
	if _, ok := tDeviceName.(string); !ok {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarg")})
	}
	deviceName := tDeviceName.(string)
	if _, ok := terms[2].(etf.List); !ok {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarg")})
	}
	isSensor, isAffector, err := parseCreateFlags(terms[2].(etf.List))
	if err != nil {
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarg")})
	}
	fullName, err := r.createDevice(fsName, deviceName, isSensor, isAffector)
	if err != nil {
		println("failed to create device: ", err)
		return etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("failed-to-create-device")})
	}
	return etf.Term(etf.Tuple{etf.Atom("ok"), fullName})
}
Esempio n. 6
0
// affecter data request
// msg must be atom `req`
func (d *deviceProc) HandleCall(msg *etf.Term, from *etf.Tuple) *etf.Term {
	println("handling call")
	if atom, ok := (*msg).(etf.Atom); !ok {
		t := etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarg")})
		return &t
	} else {
		if string(atom) != "req" {
			t := etf.Term(etf.Tuple{etf.Atom("error"), etf.Atom("badarg")})
			return &t
		}
		buf := d.device.Affect()
		if buf == nil {
			t := etf.Term(etf.Tuple{etf.Atom("ok"), etf.Atom("nil")})
			return &t
		} else {
			t := etf.Term(etf.Tuple{etf.Atom("ok"), buf})
			return &t
		}
	}
}
Esempio n. 7
0
func (rpcs *rpcRex) HandleCall(message *etf.Term, from *etf.Tuple) (reply *etf.Term) {
	nLog("REX: HandleCall: %#v, From: %#v", *message, *from)
	switch req := (*message).(type) {
	case etf.Tuple:
		if len(req) > 0 {
			switch act := req[0].(type) {
			case etf.Atom:
				if string(act) == "call" {
					nLog("RPC CALL: Module: %#v, Function: %#v, Args: %#v, GroupLeader: %#v", req[1], req[2], req[3], req[4])
					replyTerm := etf.Term(etf.Tuple{req[1], req[2]})
					reply = &replyTerm
				}
			}
		}
	}
	if reply == nil {
		replyTerm := etf.Term(etf.Tuple{etf.Atom("badrpc"), etf.Atom("unknown")})
		reply = &replyTerm
	}
	return
}
Esempio n. 8
0
func main() {
	// Parse CLI flags
	flag.Parse()

	setup_logging()
	write_pid()

	log.Println("node started")

	// Initialize new node with given name and cookie
	enode := node.NewNode(NodeName, Cookie)

	// Allow node be available on EpmdPort port
	err = enode.Publish(EpmdPort)
	if err != nil {
		log.Fatalf("Cannot publish: %s", err)
	}

	// Create channel to receive message when main process should be stopped
	completeChan := make(chan bool)

	// Initialize new instance of srv structure which implements Process behaviour
	eSrv := new(srv)

	// Spawn process with one arguments
	enode.Spawn(eSrv, completeChan)

	// RPC
	if EnableRPC {
		// Create closure
		eClos := func(terms etf.List) (r etf.Term) {
			r = etf.Term(etf.Tuple{etf.Atom("gonode"), etf.Atom("reply"), len(terms)})
			return
		}

		// Provide it to call via RPC with `rpc:call(gonode@localhost, go_rpc, call, [as, qwe])`
		err = enode.RpcProvide("go_rpc", "call", eClos)
		if err != nil {
			log.Printf("Cannot provide function to RPC: %s", err)
		}
	}

	// Wait to stop
	<-completeChan

	log.Println("node finished")

	return
}
Esempio n. 9
0
func (nk *netKernel) HandleCall(message *etf.Term, from *etf.Tuple) (reply *etf.Term) {
	nLog("NET_KERNEL: HandleCall: %#v, From: %#v", *message, *from)
	switch t := (*message).(type) {
	case etf.Tuple:
		if len(t) == 2 {
			switch tag := t[0].(type) {
			case etf.Atom:
				if string(tag) == "is_auth" {
					nLog("NET_KERNEL: is_auth: %#v", t[1])
					replyTerm := etf.Term(etf.Atom("yes"))
					reply = &replyTerm
				}
			}
		}
	}
	return
}
Esempio n. 10
0
func runNode() (enode *node.Node) {
	enode = node.NewNode(nodeName, nodeCookie)
	err := enode.Publish(nodePort)
	if err != nil {
		log.Printf("Cannot publish: %s", err)
		enode = nil
	}
	eSrv := new(eclusSrv)
	enode.Spawn(eSrv)

	eClos := func(terms etf.List) (r etf.Term) {
		r = etf.Term(etf.Tuple{etf.Atom("enode"), len(terms)})
		return
	}

	err = enode.RpcProvide("enode", "lambda", eClos)
	if err != nil {
		log.Printf("Cannot provide function to RPC: %s", err)
	}

	return
}
Esempio n. 11
0
func main() {
	// Initialize new node with given name and cookie
	enode := node.NewNode("gonode@localhost", "123")

	// Allow node be available on 5588 port
	err := enode.Publish(5588)
	if err != nil {
		log.Fatalf("Cannot publish: %s", err)
	}

	// Create channel to receive message when main process should be stopped
	completeChan := make(chan bool)

	// Initialize new instance of gonodeSrv structure which implements Process behaviour
	eSrv := new(gonodeSrv)

	// Spawn process with one arguments
	enode.Spawn(eSrv, completeChan)

	// RPC
	// Create closure
	eClos := func(terms etf.List) (r etf.Term) {
		r = etf.Term(etf.Tuple{etf.Atom("gonode"), etf.Atom("reply"), len(terms)})
		return
	}

	// Provide it to call via RPC with `rpc:call(gonode@localhost, go_rpc, call, [as, qwe])`
	err = enode.RpcProvide("go_rpc", "call", eClos)
	if err != nil {
		log.Printf("Cannot provide function to RPC: %s", err)
	}

	// Wait to stop
	<-completeChan

	return
}
Esempio n. 12
0
func (currNd *NodeDesc) ReadMessage(c net.Conn) (ts []etf.Term, err error) {

	sendData := func(headerLen int, data []byte) (int, error) {
		reply := make([]byte, len(data)+headerLen)
		if headerLen == 2 {
			binary.BigEndian.PutUint16(reply[0:headerLen], uint16(len(data)))
		} else {
			binary.BigEndian.PutUint32(reply[0:headerLen], uint32(len(data)))
		}
		copy(reply[headerLen:], data)
		dLog("Write to enode: %v", reply)
		return c.Write(reply)
	}

	switch currNd.state {
	case HANDSHAKE:
		var length uint16
		if err = binary.Read(c, binary.BigEndian, &length); err != nil {
			return
		}
		msg := make([]byte, length)
		if _, err = io.ReadFull(c, msg); err != nil {
			return
		}
		dLog("Read from enode %d: %v", length, msg)

		switch msg[0] {
		case 'n':
			sn := currNd.read_SEND_NAME(msg)
			// Statuses: ok, nok, ok_simultaneous, alive, not_allowed
			sok := currNd.compose_SEND_STATUS(sn, true)
			_, err = sendData(2, sok)
			if err != nil {
				return
			}

			rand.Seed(time.Now().UTC().UnixNano())
			currNd.challenge = rand.Uint32()

			// Now send challenge
			challenge := currNd.compose_SEND_CHALLENGE(sn)
			sendData(2, challenge)
			if err != nil {
				return
			}

		case 'r':
			sn := currNd.remote
			ok := currNd.read_SEND_CHALLENGE_REPLY(sn, msg)
			if ok {
				challengeAck := currNd.compose_SEND_CHALLENGE_ACK(sn)
				sendData(2, challengeAck)
				if err != nil {
					return
				}
				dLog("Remote: %#v", sn)
				ts = []etf.Term{etf.Term(etf.Tuple{etf.Atom("$go_set_node"), etf.Atom(sn.Name)})}
			} else {
				err = errors.New("bad handshake")
				return
			}
		}

	case CONNECTED:
		var length uint32
		if err = binary.Read(c, binary.BigEndian, &length); err != nil {
			return
		}
		if length == 0 {
			dLog("Keepalive")
			sendData(4, []byte{})
			return
		}
		r := &io.LimitedReader{c, int64(length)}

		if currNd.flag.isSet(DIST_HDR_ATOM_CACHE) {
			var ctl, message etf.Term
			if err = currNd.readDist(r); err != nil {
				break
			}
			if ctl, err = currNd.readCtl(r); err != nil {
				break
			}
			dLog("READ CTL: %#v", ctl)

			if message, err = currNd.readMessage(r); err != nil {
				break
			}
			dLog("READ MESSAGE: %#v", message)
			ts = append(ts, ctl, message)

		} else {
			msg := make([]byte, 1)
			if _, err = io.ReadFull(r, msg); err != nil {
				return
			}
			dLog("Read from enode %d: %#v", length, msg)

			switch msg[0] {
			case 'p':
				ts = make([]etf.Term, 0)
				for {
					var res etf.Term
					if res, err = currNd.readTerm(r); err != nil {
						break
					}
					ts = append(ts, res)
					dLog("READ TERM: %#v", res)
				}
				if err == io.EOF {
					err = nil
				}

			default:
				_, err = ioutil.ReadAll(r)
			}
		}

	}

	return
}
Esempio n. 13
0
func (es *eclusSrv) HandleCall(message *etf.Term, from *etf.Tuple) (reply *etf.Term) {
	log.Printf("ECLUS_SRV: HandleCall: %#v, From: %#v", *message, *from)
	replyTerm := etf.Term(etf.Tuple{etf.Atom("ok"), etf.Atom("eclus_reply"), *message})
	reply = &replyTerm
	return
}
Esempio n. 14
0
func (gns *globalNameServer) HandleCall(message *etf.Term, from *etf.Tuple) (reply *etf.Term) {
	nLog("GLOBAL_NAME_SERVER: HandleCall: %#v, From: %#v", *message, *from)
	replyTerm := etf.Term(etf.Atom("reply"))
	reply = &replyTerm
	return
}