-
Notifications
You must be signed in to change notification settings - Fork 1
/
AccountWiseLedgerDNS.py
146 lines (124 loc) · 6.3 KB
/
AccountWiseLedgerDNS.py
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
import threading
import socket
import json
import platform
import os
import sys
from pprint import pprint
class AccountWiseLedgerDNS(object):
def __init__(self, K):
self.__socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.__platform = platform.system()
self.__ip = self.__getHostnameIP()
self.__port = 8000
self.__socketBufferSize = 64 * 1024 * 1024
self.__K_numOfSubNetwork = K
self.__DNSTable = {}
self.__resetDNSTable()
try:
self.__socket.bind((self.__ip, self.__port))
print("DNS is hosted on [", self.__platform, "]. The IP/Port is [", self.__ip + ":" + str(self.__port), "]. Type in \"man\" to browse available commands")
except:
print("Error occurred. Server shutdown...")
return
def __resetDNSTable(self):
self.__DNSTable = {
"all": {},
"nodeToSubNetwork": {},
"subNetworkToNode": {networkIndex: {} for networkIndex in range(self.__K_numOfSubNetwork)},
"subNetworkToIndex": {networkIndex: {} for networkIndex in range(self.__K_numOfSubNetwork)},
"sizeOfSubNetwork": {networkIndex: 0 for networkIndex in range(self.__K_numOfSubNetwork)}
}
def __getHostnameIP(self):
try:
tmpS = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
tmpS.connect(("8.8.8.8", 80))
ans = tmpS.getsockname()[0]
tmpS.close()
return ans
except:
return None
def listen(self):
while True:
try:
inputMsg, sourceAddress = self.__socket.recvfrom(self.__socketBufferSize)
inputMsg = json.loads(inputMsg.decode())
newPeer = None
except ConnectionResetError:
print("Error occurred. Server shutdown...")
sys.exit(0)
if inputMsg["type"] == "exit":
break
else:
print(sourceAddress, "a.k.a [", inputMsg["senderID"], "] is connected. Action Type [", inputMsg["type"], "]\n" + "[" + socket.gethostname().strip() + " @ " + self.__ip + ":" + str(self.__port) + "] $ ", end="")
if inputMsg["type"] == "New Peer":
if inputMsg["senderID"] not in self.__DNSTable["all"]:
newPeer = inputMsg["senderID"]
assignedSubNetworkIndex = min(self.__DNSTable["sizeOfSubNetwork"].keys(), key=lambda x: self.__DNSTable["sizeOfSubNetwork"][x])
self.__DNSTable["subNetworkToNode"][assignedSubNetworkIndex][inputMsg["senderID"]] = len(self.__DNSTable["subNetworkToNode"][assignedSubNetworkIndex])
self.__DNSTable["subNetworkToIndex"][assignedSubNetworkIndex][str(len(self.__DNSTable["subNetworkToIndex"][assignedSubNetworkIndex]))] = inputMsg["senderID"]
self.__DNSTable["nodeToSubNetwork"][inputMsg["senderID"]] = assignedSubNetworkIndex
self.__DNSTable["sizeOfSubNetwork"][assignedSubNetworkIndex] += 1
self.__DNSTable["all"][inputMsg["senderID"]] = sourceAddress
outputMsg = {"type": "DNS update", "data": self.__DNSTable, "newPeer": newPeer}
for nodeAddr in self.__DNSTable["all"].values():
self.__socket.sendto(json.dumps(outputMsg).encode(), nodeAddr)
elif inputMsg["type"] == "Request DNS Update":
self.__DNSTable["all"][inputMsg["senderID"]] = sourceAddress
outputMsg = {"type": "DNS update", "data": self.__DNSTable, "newPeer": newPeer}
self.__socket.sendto(json.dumps(outputMsg).encode(), sourceAddress)
def send(self):
while True:
print("[" + socket.gethostname().strip() + " @ " + self.__ip + ":" + str(self.__port) + "] $ ", end="")
inputMsg = input()
if inputMsg == "exit":
self.__socket.sendto(json.dumps({"type": "exit"}).encode(), (self.__ip, self.__port))
break
elif inputMsg == "ls":
pprint(self.__DNSTable)
elif inputMsg == "re":
self.__resetDNSTable()
print("DNS table is cleaned up.")
elif inputMsg == "cls":
if self.__platform == "Windows":
os.system("cls")
else:
os.system("clear")
elif inputMsg[:4] == "setk":
try:
self.__K_numOfSubNetwork = int(inputMsg.split(" ")[1])
self.__resetDNSTable()
print("The number of Sub-Networks has been set to: ", self.__K_numOfSubNetwork)
except (IndexError, ValueError):
print("Please insert a valid number.")
elif inputMsg == "cfg":
print("Current Local Administrator: ", socket.gethostname())
print("System Platform: ", self.__platform)
print("IP Address: ", self.__ip)
print("Port Number: ", self.__port)
print("Socket Buffer Size: ", self.__socketBufferSize)
print("Designated number of Sub-Networks: ", self.__K_numOfSubNetwork)
elif inputMsg == "man":
manual = {
"ls": "List down the current DNS table",
"re": "Clean up the DNS table",
"cls": "Clean up the console out",
"setk": "Re-define the number of Sub-Networks",
"cfg": "Show all network settings",
"man": "Show all available commands",
"exit": "Shutdown the DNS"
}
print("The following commands are available:")
for index, item in enumerate(manual):
print(index, ". ", item, "\t", manual[item])
else:
print("Unknown command.")
def main():
K_numOfSubNetwork = int(input("The number of Sub-Networks K (default = 1): ") or 1)
myDNS = AccountWiseLedgerDNS(K_numOfSubNetwork)
threadListen = threading.Thread(target=myDNS.listen, args=())
threadSend = threading.Thread(target=myDNS.send, args=())
threadListen.start()
threadSend.start()
if __name__ == "__main__":
main()