summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/sample/wg_tunnel/fsm.go
blob: 965f6fca925459b069a41881749e645511485ee0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package main

import (
	"fmt"
//	"log"
	"github.com/insomniacslk/dhcp/dhcpv6"
)

// FSM from RFC 2131 Figure 5

type DHCP interface {
	SendDiscover()
	SendRequest()
}

type FSM struct {
	state State
	dhcp DHCP
}

type DHCPv4 struct {
}

func (f FSM) Init(d DHCP) {
	fmt.Println("Init")
	f.dhcp = d
	f.state = stInit(f.dhcp, nil)

	//	go 
}

func (f FSM) InputMessage() {
}

func (d DHCPv4) SendDiscover() {
}

type DHCPv6 struct {
}

func (d DHCPv6) SendDiscover() {
	fmt.Println("SendDiscover")
}

func (d DHCPv6) SendRequest() {
	fmt.Println("SendRequest")
}

type EventType uint8

const (
	EventTypeNone         EventType = 0
	EventTypeMessage      EventType = 1
	EventTypeTimeoutT1    EventType = 2
	EventTypeTimeoutT2    EventType = 3
	EventTypeTimeoutLease EventType = 3
)

type Event interface {
	Type() EventType
}

// type TimerType uint8

// const (
// 	TimerNone  TimerType = 0
// 	TimerT1    TimerType = 1
// 	TimerT2    TimerType = 2
// 	TimerLease TimerType = 3
// )

// type EventTimeout struct {
// 	Event
// 	Timer TimerType
// }

type EventMessage struct {
	Event
	msg dhcpv6.Message
}

func (ev *EventMessage) Type() EventType {
	return EventTypeMessage
}

func (ev *EventMessage) Msg() dhcpv6.Message {
	return ev.msg
}

type State func (d DHCP, ev Event) (next State)

func stInit(d DHCP, ev Event) State {
	// Send Discover
	d.SendDiscover()
	return stSelecting
}

func stSelecting(d DHCP, ev Event) State {
	switch ev.Type() {
	case EventTypeMessage:
		msg := ev.(*EventMessage).Msg()
		switch msg.Type() {
		case dhcpv6.MessageTypeAdvertise:
			// Select first offer
			d.SendRequest()
			return stRequesting
		}
	}
	return stSelecting
}

func stRequesting(d DHCP, ev Event) State {
	switch ev.Type() {
	case EventTypeMessage:
		msg := ev.(*EventMessage).Msg()
		switch msg.Type() {
		case dhcpv6.MessageTypeAdvertise:
			// Discard
			return stRequesting
		case dhcpv6.MessageTypeReply:
			// Record lease, set T1, T2
			return stBound
		case dhcpv6.MessageTypeNone: // FIXME NAK
			// Send Decline
			return stInit
		}
	}
	return stRequesting
}

func stBound(d DHCP, ev Event) State {
	switch ev.Type() {
	case EventTypeTimeoutT1:
		// Send Request
		return stRenewing
	case  EventTypeMessage:
		msg := ev.(*EventMessage).Msg()
		switch msg.Type() {
		case dhcpv6.MessageTypeAdvertise:
		case dhcpv6.MessageTypeReply:
		case dhcpv6.MessageTypeNone:
			// TODO or NACK
			// Send Decline
			return stBound
		}
	}		
	return stBound
}

func stRenewing(d DHCP, ev Event) State {
	// FIXME
	switch ev.Type() {
	case EventTypeTimeoutT2:
		// Broadcast request?
		return stRebinding
	case EventTypeMessage:
		msg := ev.(*EventMessage).Msg()
		switch msg.Type() {
		case dhcpv6.MessageTypeReply:
			// Record lease, set T1, T2
			return stBound
		case dhcpv6.MessageTypeNone: // FIXME NAK
			// HALT network
			return stInit
		}
	}
	return stRenewing
}

func stRebinding(d DHCP, ev Event) State {
	switch ev.Type() {
	case EventTypeTimeoutLease:
		// Halt network
		return stInit
	case EventTypeMessage:
		msg := ev.(*EventMessage).Msg()
		switch msg.Type() {
		case dhcpv6.MessageTypeReply:
			// Record lease, set timers T1, T2
			return stBound
		case dhcpv6.MessageTypeNone: // FIXME NAK
			// Halt network
			return stInit
		}
	}
	return stRebinding
}