/* ** This file is part of Filius, a network construction and simulation software. ** ** Originally created at the University of Siegen, Institute "Didactics of ** Informatics and E-Learning" by a students' project group: ** members (2006-2007): ** André Asschoff, Johannes Bade, Carsten Dittich, Thomas Gerding, ** Nadja Haßler, Ernst Johannes Klebert, Michell Weyer ** supervisors: ** Stefan Freischlad (maintainer until 2009), Peer Stechert ** Project is maintained since 2010 by Christian Eibl <filius@c.fameibl.de> ** and Stefan Freischlad ** Filius is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 2 of the License, or ** (at your option) version 3. ** ** Filius is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Filius. If not, see <http://www.gnu.org/licenses/>. */ package filius.software.dns; import java.util.LinkedList; import java.util.ListIterator; import java.util.StringTokenizer; import filius.Main; import filius.software.clientserver.UDPServerAnwendung; import filius.software.system.Datei; import filius.software.system.Dateisystem; import filius.software.transportschicht.Socket; public class DNSServer extends UDPServerAnwendung { private LinkedList<ResourceRecord> records = new LinkedList<ResourceRecord>(); public DNSServer() { super(); Main.debug.println("INVOKED-2 ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), constr: DNSServer()"); setPort(53); } public void starten() { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), starten()"); super.starten(); if (!getSystemSoftware().getDateisystem().dateiVorhanden("dns", "hosts")) { getSystemSoftware().getDateisystem().erstelleVerzeichnis("root", "dns"); } initialisiereRecordListe(); } public void beenden() { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), beenden()"); super.beenden(); } public LinkedList<ResourceRecord> holeResourceRecords() { this.initialisiereRecordListe(); return records; } public void hinzuRecord(String domainname, String typ, String rdata) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), hinzuRecord("+domainname+","+typ+","+rdata+")"); ResourceRecord rr; rr = new ResourceRecord(domainname, typ, rdata); records.add(rr); this.schreibeRecordListe(); } private void initialisiereRecordListe() { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+", initialisiereRecordListe()"); Datei hosts; StringTokenizer tokenizer; String line; ResourceRecord rr; Dateisystem dateisystem; LinkedList<ResourceRecord> tmp; tmp = new LinkedList<ResourceRecord>(); dateisystem = getSystemSoftware().getDateisystem(); hosts = dateisystem.holeDatei(dateisystem.holeRootPfad()+Dateisystem.FILE_SEPARATOR+"dns"+Dateisystem.FILE_SEPARATOR+"hosts"); if (hosts != null) { tokenizer = new StringTokenizer(hosts.getDateiInhalt(), "\n"); while (tokenizer.hasMoreTokens()) { line = tokenizer.nextToken().trim(); if (!line.equals("") && !(line.split(" ", 5).length<4)) { rr = new ResourceRecord(line); tmp.add(rr); } } } records = tmp; } private void schreibeRecordListe() { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), schreibeRecordListe()"); Datei hosts; StringBuffer text; ListIterator<ResourceRecord> it; Dateisystem dateisystem; dateisystem = getSystemSoftware().getDateisystem(); text = new StringBuffer(); it = records.listIterator(); while (it.hasNext()) { text.append(it.next().toString()+"\n"); } hosts = new Datei(); hosts.setDateiInhalt(text.toString()); hosts.setName("hosts"); dateisystem.speicherDatei(dateisystem.holeRootPfad()+Dateisystem.FILE_SEPARATOR+"dns", hosts); } public void changeSingleEntry(int recordIdx, int partIdx, String type, String newValue) { Main.debug.println("INVOKED ("+this.hashCode()+") "+getClass()+", changeSingleEntry("+recordIdx+","+partIdx+","+type+","+newValue+")"); ListIterator<ResourceRecord> it = records.listIterator(); ResourceRecord rrec = null; int countA = 0; while (it.hasNext()) { // iterating whole list is necessary, since MX and A records are mixed in the records list! :-( rrec = it.next(); if (rrec.getType().equals(type)) { countA++; } if (countA-1 == recordIdx) { // found A entry with (filtered) index recordIdx // Main.debug.println("DEBUG ("+this.hashCode()+") "+getClass()+", changeSingleEntry: aktuell: countA="+countA+", rrec="+rrec); if(partIdx == 0) { // change URL rrec.setDomainname(newValue); } else if(partIdx == 3) { // change IP rrec.setRdata(newValue); } } } this.schreibeRecordListe(); } public void loescheResourceRecord(String domainname, String typ) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), loescheResourceRecord("+domainname+","+typ+")"); ResourceRecord rr; ListIterator<ResourceRecord> it; boolean fertig = false; it = records.listIterator(); while (!fertig && it.hasNext()) { rr = (ResourceRecord)it.next(); if (rr.getDomainname().equalsIgnoreCase(domainname) && rr.getType().equals(typ)) { records.remove(rr); fertig = true; } } this.schreibeRecordListe(); } public ResourceRecord holeRecord(String domainname, String typ) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), holeRecord("+domainname+","+typ+")"); for (ResourceRecord rr : records) { if (rr.getDomainname().equalsIgnoreCase(domainname) && rr.getType().equals(typ)) { return rr; } } return null; } public ResourceRecord holeRecord(String domainname) { String domain; String[] parts = domainname.split("\\."); for (int i = 0; i < parts.length; i++) { domain = this.implodeDomain(parts, i); for (ResourceRecord rr : records) { if (rr.getDomainname().equalsIgnoreCase(domain)) { return rr; } } } return null; } private String implodeDomain(String[] parts, int start) { StringBuffer domain = new StringBuffer(); for (int i=start; i<parts.length; i++) { domain.append(parts[i]); if (i < parts.length-1) { domain.append("."); } } return domain.toString(); } protected void neuerMitarbeiter(Socket socket) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (DNSServer), neuerMitarbeiter("+socket+")"); DNSServerMitarbeiter dnsMitarbeiter; dnsMitarbeiter = new DNSServerMitarbeiter(this, socket); dnsMitarbeiter.starten(); mitarbeiter.add(dnsMitarbeiter); } }