mirror of https://github.com/jetkvm/kvm.git
Compare commits
1 Commits
ffff27eb68
...
746779b907
| Author | SHA1 | Date |
|---|---|---|
|
|
746779b907 |
17
network.go
17
network.go
|
|
@ -110,13 +110,6 @@ func triggerTimeSyncOnNetworkStateChange() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPublicIPReadyState(ipv4Ready, ipv6Ready bool) {
|
|
||||||
if publicIPState == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
publicIPState.SetIPv4AndIPv6(ipv4Ready, ipv6Ready)
|
|
||||||
}
|
|
||||||
|
|
||||||
func networkStateChanged(_ string, state types.InterfaceState) {
|
func networkStateChanged(_ string, state types.InterfaceState) {
|
||||||
// do not block the main thread
|
// do not block the main thread
|
||||||
go waitCtrlAndRequestDisplayUpdate(true, "network_state_changed")
|
go waitCtrlAndRequestDisplayUpdate(true, "network_state_changed")
|
||||||
|
|
@ -128,9 +121,15 @@ func networkStateChanged(_ string, state types.InterfaceState) {
|
||||||
if state.Online {
|
if state.Online {
|
||||||
networkLogger.Info().Msg("network state changed to online, triggering time sync")
|
networkLogger.Info().Msg("network state changed to online, triggering time sync")
|
||||||
triggerTimeSyncOnNetworkStateChange()
|
triggerTimeSyncOnNetworkStateChange()
|
||||||
}
|
|
||||||
|
|
||||||
setPublicIPReadyState(state.IPv4Ready, state.IPv6Ready)
|
if publicIPState != nil {
|
||||||
|
publicIPState.SetIPv4AndIPv6(state.IPv4Ready, state.IPv6Ready)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if publicIPState != nil {
|
||||||
|
publicIPState.SetIPv4AndIPv6(false, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// always restart mDNS when the network state changes
|
// always restart mDNS when the network state changes
|
||||||
if mDNS != nil {
|
if mDNS != nil {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -53,38 +52,21 @@ func (ps *PublicIPState) checkCloudflare(ctx context.Context, family int) (*Publ
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
values := make(map[string]string)
|
|
||||||
for line := range strings.SplitSeq(string(body), "\n") {
|
for line := range strings.SplitSeq(string(body), "\n") {
|
||||||
key, value, ok := strings.Cut(line, "=")
|
key, value, ok := strings.Cut(line, "=")
|
||||||
if !ok {
|
if !ok || key != "ip" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
values[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
ps.lastUpdated = time.Now()
|
|
||||||
if ts, ok := values["ts"]; ok {
|
|
||||||
if ts, err := strconv.ParseFloat(ts, 64); err == nil {
|
|
||||||
ps.lastUpdated = time.Unix(int64(ts), 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ipStr, ok := values["ip"]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("no IP address found")
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := net.ParseIP(ipStr)
|
|
||||||
if ip == nil {
|
|
||||||
return nil, fmt.Errorf("invalid IP address: %s", ipStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &PublicIP{
|
return &PublicIP{
|
||||||
IPAddress: ip,
|
IPAddress: net.ParseIP(value),
|
||||||
LastUpdated: ps.lastUpdated,
|
LastUpdated: time.Now(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("no IP address found")
|
||||||
|
}
|
||||||
|
|
||||||
// checkAPI uses the API endpoint to get the public IP address
|
// checkAPI uses the API endpoint to get the public IP address
|
||||||
func (ps *PublicIPState) checkAPI(_ context.Context, _ int) (*PublicIP, error) {
|
func (ps *PublicIPState) checkAPI(_ context.Context, _ int) (*PublicIP, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,22 @@ func (ps *PublicIPState) SetIPv4AndIPv6(ipv4, ipv6 bool) {
|
||||||
ps.ipv6 = ipv6
|
ps.ipv6 = ipv6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetIPv4 sets if we need to track IPv4 public IP addresses
|
||||||
|
func (ps *PublicIPState) SetIPv4(ipv4 bool) {
|
||||||
|
ps.mu.Lock()
|
||||||
|
defer ps.mu.Unlock()
|
||||||
|
|
||||||
|
ps.ipv4 = ipv4
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIPv6 sets if we need to track IPv6 public IP addresses
|
||||||
|
func (ps *PublicIPState) SetIPv6(ipv6 bool) {
|
||||||
|
ps.mu.Lock()
|
||||||
|
defer ps.mu.Unlock()
|
||||||
|
|
||||||
|
ps.ipv6 = ipv6
|
||||||
|
}
|
||||||
|
|
||||||
// SetCloudflareEndpoint sets the Cloudflare endpoint
|
// SetCloudflareEndpoint sets the Cloudflare endpoint
|
||||||
func (ps *PublicIPState) SetCloudflareEndpoint(endpoint string) {
|
func (ps *PublicIPState) SetCloudflareEndpoint(endpoint string) {
|
||||||
ps.mu.Lock()
|
ps.mu.Lock()
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,8 @@ import { PublicIP } from "@hooks/stores";
|
||||||
import { m } from "@localizations/messages.js";
|
import { m } from "@localizations/messages.js";
|
||||||
import { JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc";
|
import { JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc";
|
||||||
import notifications from "@/notifications";
|
import notifications from "@/notifications";
|
||||||
import { formatters } from "@/utils";
|
|
||||||
|
|
||||||
|
|
||||||
const TimeAgoLabel = ({ date }: { date: Date }) => {
|
|
||||||
const [timeAgo, setTimeAgo] = useState<string | undefined>(formatters.timeAgo(date));
|
|
||||||
useEffect(() => {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
setTimeAgo(formatters.timeAgo(date));
|
|
||||||
}, 1000);
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, [date]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span className="text-sm text-slate-600 dark:text-slate-400 select-none">
|
|
||||||
{timeAgo}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function PublicIPCard() {
|
export default function PublicIPCard() {
|
||||||
const { send } = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
||||||
|
|
@ -38,8 +21,6 @@ export default function PublicIPCard() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const publicIPs = resp.result as PublicIP[];
|
const publicIPs = resp.result as PublicIP[];
|
||||||
// sort the public IPs by IP address
|
|
||||||
// IPv6 addresses are sorted after IPv4 addresses
|
|
||||||
setPublicIPs(publicIPs.sort(({ ip: aIp }, { ip: bIp }) => {
|
setPublicIPs(publicIPs.sort(({ ip: aIp }, { ip: bIp }) => {
|
||||||
const aIsIPv6 = aIp.includes(":");
|
const aIsIPv6 = aIp.includes(":");
|
||||||
const bIsIPv6 = bIp.includes(":");
|
const bIsIPv6 = bIp.includes(":");
|
||||||
|
|
@ -93,7 +74,6 @@ export default function PublicIPCard() {
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
{ip.ip}
|
{ip.ip}
|
||||||
</span>
|
</span>
|
||||||
{ip.last_updated && <TimeAgoLabel date={new Date(ip.last_updated)} />}
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue