network.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package main
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strconv"
  6. "imuslab.com/arozos/mod/common"
  7. network "imuslab.com/arozos/mod/network"
  8. mdns "imuslab.com/arozos/mod/network/mdns"
  9. "imuslab.com/arozos/mod/network/netstat"
  10. ssdp "imuslab.com/arozos/mod/network/ssdp"
  11. upnp "imuslab.com/arozos/mod/network/upnp"
  12. "imuslab.com/arozos/mod/network/websocket"
  13. prout "imuslab.com/arozos/mod/prouter"
  14. "imuslab.com/arozos/mod/www"
  15. )
  16. var (
  17. MDNS *mdns.MDNSHost
  18. UPNP *upnp.UPnPClient
  19. SSDP *ssdp.SSDPHost
  20. WebSocketRouter *websocket.Router
  21. )
  22. func NetworkServiceInit() {
  23. systemWideLogger.PrintAndLog("Network", "Starting ArOZ Network Services", nil)
  24. //Create a router that allow users with System Setting access to access these api endpoints
  25. router := prout.NewModuleRouter(prout.RouterOption{
  26. ModuleName: "System Setting",
  27. AdminOnly: false,
  28. UserHandler: userHandler,
  29. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  30. common.SendErrorResponse(w, "Permission Denied")
  31. },
  32. })
  33. /*
  34. Standard Network Utilties
  35. */
  36. //Register handler endpoints
  37. if *allow_hardware_management {
  38. router.HandleFunc("/system/network/getNICinfo", network.GetNICInfo)
  39. router.HandleFunc("/system/network/getPing", network.GetPing)
  40. //Register as a system setting
  41. registerSetting(settingModule{
  42. Name: "Network Info",
  43. Desc: "System Information",
  44. IconPath: "SystemAO/network/img/ethernet.png",
  45. Group: "Network",
  46. StartDir: "SystemAO/network/hardware.html",
  47. })
  48. }
  49. router.HandleFunc("/system/network/getNICUsage", netstat.HandleGetNetworkInterfaceStats)
  50. //Start the services that depends on network interface
  51. StartNetworkServices()
  52. //Start the port forward configuration interface
  53. portForwardInit()
  54. //Start userhomepage if enabled
  55. //Handle user webroot routings if homepage is enabled
  56. if *allow_homepage {
  57. userWwwHandler = www.NewWebRootHandler(www.Options{
  58. UserHandler: userHandler,
  59. Database: sysdb,
  60. AgiGateway: AGIGateway,
  61. })
  62. router.HandleFunc("/system/network/www/toggle", userWwwHandler.HandleToggleHomepage)
  63. router.HandleFunc("/system/network/www/webRoot", userWwwHandler.HandleSetWebRoot)
  64. //Register as a system setting
  65. registerSetting(settingModule{
  66. Name: "Personal Page",
  67. Desc: "Personal Web Page",
  68. IconPath: "SystemAO/www/img/homepage.png",
  69. Group: "Network",
  70. StartDir: "SystemAO/www/config.html",
  71. })
  72. }
  73. userRouter := prout.NewModuleRouter(prout.RouterOption{
  74. AdminOnly: false,
  75. UserHandler: userHandler,
  76. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  77. common.SendErrorResponse(w, "Permission Denied")
  78. },
  79. })
  80. WebSocketRouter = websocket.NewRouter()
  81. userRouter.HandleFunc("/system/ws", WebSocketRouter.HandleWebSocketRouting)
  82. }
  83. func StartNetworkServices() {
  84. /*
  85. MDNS Services
  86. */
  87. if *allow_mdns {
  88. m, err := mdns.NewMDNS(mdns.NetworkHost{
  89. HostName: *host_name + "_" + deviceUUID, //To handle more than one identical model within the same network, this must be unique
  90. Port: *listen_port,
  91. Domain: "arozos.com",
  92. Model: deviceModel,
  93. UUID: deviceUUID,
  94. Vendor: deviceVendor,
  95. BuildVersion: build_version,
  96. MinorVersion: internal_version,
  97. })
  98. if err != nil {
  99. systemWideLogger.PrintAndLog("Network", "MDNS Startup Failed. Running in Offline Mode.", err)
  100. } else {
  101. MDNS = m
  102. }
  103. }
  104. /*
  105. SSDP Discovery Services
  106. */
  107. if *allow_ssdp {
  108. //Get outbound ip
  109. obip, err := network.GetOutboundIP()
  110. if err != nil {
  111. systemWideLogger.PrintAndLog("Network", "SSDP Startup Failed. Running in Offline Mode.", err)
  112. } else {
  113. thisIp := obip.String()
  114. adv, err := ssdp.NewSSDPHost(thisIp, *listen_port, "system/ssdp.xml", ssdp.SSDPOption{
  115. URLBase: "http://" + thisIp + ":" + strconv.Itoa(*listen_port), //This must be http if used as local hosting devices
  116. Hostname: *host_name,
  117. Vendor: deviceVendor,
  118. VendorURL: deviceVendorURL,
  119. ModelName: deviceModel,
  120. ModelDesc: deviceModelDesc,
  121. UUID: deviceUUID,
  122. Serial: "generic",
  123. })
  124. if err != nil {
  125. systemWideLogger.PrintAndLog("Network", "SSDP Startup Failed. Running in Offline Mode.", err)
  126. } else {
  127. //OK! Start SSDP Service
  128. SSDP = adv
  129. SSDP.Start()
  130. }
  131. }
  132. }
  133. /*
  134. UPNP / Setup automatic port forwarding
  135. */
  136. if *allow_upnp {
  137. var u *upnp.UPnPClient
  138. var err error = nil
  139. if *use_tls {
  140. u, err = upnp.NewUPNPClient(*tls_listen_port, *host_name+"-https")
  141. } else {
  142. u, err = upnp.NewUPNPClient(*listen_port, *host_name+"-http")
  143. }
  144. if err != nil {
  145. systemWideLogger.PrintAndLog("Network", "UPnP Startup Failed: "+err.Error(), err)
  146. } else {
  147. //Bind the http port if running in https and http server is not disabled
  148. if *use_tls && !*disable_http {
  149. u.ForwardPort(*listen_port, *host_name+"-http")
  150. }
  151. UPNP = u
  152. //Register nightly listener for upnp renew
  153. nightlyManager.RegisterNightlyTask(func() {
  154. UPNP.RenewForwardRules()
  155. })
  156. //Show a tip for success port forward
  157. connectionEndpoint := UPNP.ExternalIP + ":" + strconv.Itoa(*listen_port)
  158. obip, err := network.GetOutboundIP()
  159. obipstring := "[Outbound IP]"
  160. if err != nil {
  161. } else {
  162. obipstring = obip.String()
  163. }
  164. localEndpoint := obipstring + ":" + strconv.Itoa(*listen_port)
  165. systemWideLogger.PrintAndLog("Network", "Automatic Port Forwarding Completed. Forwarding all request from "+connectionEndpoint+" to "+localEndpoint, nil)
  166. }
  167. }
  168. }
  169. func StopNetworkServices() {
  170. //systemWideLogger.PrintAndLog("Shutting Down Network Services...",nil)
  171. //Shutdown uPNP service if enabled
  172. if *allow_upnp {
  173. systemWideLogger.PrintAndLog("System", "<!> Shutting down uPNP service", nil)
  174. UPNP.Close()
  175. }
  176. //Shutdown SSDP service if enabled
  177. if *allow_ssdp {
  178. systemWideLogger.PrintAndLog("System", "<!> Shutting down SSDP service", nil)
  179. SSDP.Close()
  180. }
  181. //Shutdown MDNS if enabled
  182. if *allow_mdns {
  183. systemWideLogger.PrintAndLog("System", "<!> Shutting down MDNS service", nil)
  184. MDNS.Close()
  185. }
  186. }
  187. /*
  188. File Server Services
  189. */
  190. type NetworkFileServer struct {
  191. Name string //Name of the File Server Type. E.g. FTP
  192. Desc string //Description of the File Server Type, e.g. File Transfer Protocol
  193. IconPath string //Path for the protocol Icon, if any
  194. DefaultPorts []int //Default ports aquire by the Server. Override by Ports if set
  195. Ports []int //Ports required by the File Server Type that might need port forward. e.g. 21, 22
  196. Enabled bool //If the server is enabled
  197. ForwardPortIfUpnp bool //Forward the port if UPnP is enabled
  198. ConnInstrPage string //Connection instruction page, visable by all users
  199. ConfigPage string //Config page for changing settings of this File Server Type, admin only
  200. InitFunc func() `json:"-"` //Startup function for this service
  201. }
  202. var networkFileServerDaemon []NetworkFileServer = []NetworkFileServer{}
  203. //Initiate all File Server services
  204. func FileServerInit() {
  205. //Register System Setting
  206. registerSetting(settingModule{
  207. Name: "File Servers",
  208. Desc: "Network File Transfer Servers",
  209. IconPath: "SystemAO/disk/smart/img/small_icon.png",
  210. Group: "Network",
  211. StartDir: "SystemAO/disk/services.html",
  212. RequireAdmin: false,
  213. })
  214. //Create a request router
  215. router := prout.NewModuleRouter(prout.RouterOption{
  216. ModuleName: "System Setting",
  217. AdminOnly: false,
  218. UserHandler: userHandler,
  219. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  220. common.SendErrorResponse(w, "Permission Denied")
  221. },
  222. })
  223. networkFileServerDaemon = append(networkFileServerDaemon, NetworkFileServer{
  224. Name: "FTP",
  225. Desc: "File Transfer Protocol Server",
  226. IconPath: "SystemAO/disk/smart/img/small_icon.png",
  227. DefaultPorts: []int{21, 22, 23},
  228. Ports: []int{},
  229. ForwardPortIfUpnp: true,
  230. ConnInstrPage: "SystemAO/disk/ftp.html",
  231. ConfigPage: "SystemAO/disk/ftp.html",
  232. InitFunc: FTPServerInit,
  233. })
  234. networkFileServerDaemon = append(networkFileServerDaemon, NetworkFileServer{
  235. Name: "WebDAV",
  236. Desc: "WebDAV Server",
  237. IconPath: "SystemAO/disk/smart/img/small_icon.png",
  238. DefaultPorts: []int{},
  239. Ports: []int{},
  240. ForwardPortIfUpnp: false,
  241. ConnInstrPage: "SystemAO/disk/webdav.html",
  242. ConfigPage: "SystemAO/disk/webdav.html",
  243. InitFunc: WebDAVInit,
  244. })
  245. //Initiate all Network File Servers by calling their init Function
  246. for _, nfsd := range networkFileServerDaemon {
  247. nfsd.InitFunc()
  248. }
  249. router.HandleFunc("/system/network/fs/list", NetworkHandleGetFileServerServiceList)
  250. }
  251. func NetworkHandleGetFileServerServiceList(w http.ResponseWriter, r *http.Request) {
  252. js, _ := json.Marshal(networkFileServerDaemon)
  253. common.SendJSONResponse(w, string(js))
  254. }