From 7038384d367d1dd0d532f3a9dd430a5552aca9ab Mon Sep 17 00:00:00 2001 From: Andrew Hennessy Date: Mon, 4 Nov 2013 17:13:13 -0500 Subject: [PATCH] mDNS no longer crashes on malformed packets --- .classpath | 1 + gen/com/limelight/R.java | 10 +- libs/{dnsjava-2.1.5.jar => dnsjava-2.1.6.jar} | Bin 301194 -> 302025 bytes res/layout/activity_connection.xml | 6 +- src/com/limelight/Connection.java | 29 +- src/com/limelight/nvstream/NvComputer.java | 70 +--- src/com/limelight/nvstream/NvmDNS.java | 328 +++++++++--------- 7 files changed, 193 insertions(+), 251 deletions(-) rename libs/{dnsjava-2.1.5.jar => dnsjava-2.1.6.jar} (81%) diff --git a/.classpath b/.classpath index 7bc01d9a..e5f25532 100644 --- a/.classpath +++ b/.classpath @@ -5,5 +5,6 @@ + diff --git a/gen/com/limelight/R.java b/gen/com/limelight/R.java index 47c9ea76..3395dcbb 100644 --- a/gen/com/limelight/R.java +++ b/gen/com/limelight/R.java @@ -35,15 +35,11 @@ or to a theme attribute in the form "?[package:][type:]na public static final int ic_launcher=0x7f020000; } public static final class id { -<<<<<<< HEAD - public static final int mDNSResultView=0x7f080000; - public static final int surfaceView=0x7f080001; -======= - public static final int hostTextView=0x7f080002; + public static final int hostTextView=0x7f080003; + public static final int mDNSResultView=0x7f080002; public static final int pairButton=0x7f080000; public static final int statusButton=0x7f080001; - public static final int surfaceView=0x7f080003; ->>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d + public static final int surfaceView=0x7f080004; } public static final class layout { public static final int activity_connection=0x7f030000; diff --git a/libs/dnsjava-2.1.5.jar b/libs/dnsjava-2.1.6.jar similarity index 81% rename from libs/dnsjava-2.1.5.jar rename to libs/dnsjava-2.1.6.jar index e928fad994384772d71ff1bc0ab5e1cabfd74786..6bd9b2eeefd21f0e5b37cae3d725bc8c561d8ecd 100644 GIT binary patch delta 40589 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

*BbwJrCdNvJed#LQ2FAQu|SRC`9{u(ug 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
    07KMJqw9*PT>>z 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 diff --git a/res/layout/activity_connection.xml b/res/layout/activity_connection.xml index 4ef82e8f..c7ad9d47 100644 --- a/res/layout/activity_connection.xml +++ b/res/layout/activity_connection.xml @@ -16,7 +16,7 @@ android:layout_centerHorizontal="true" android:text="Pair with PC"/> -<<<<<<< HEAD + -======= + ->>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d + diff --git a/src/com/limelight/Connection.java b/src/com/limelight/Connection.java index fd398ad3..5e80d252 100644 --- a/src/com/limelight/Connection.java +++ b/src/com/limelight/Connection.java @@ -1,13 +1,8 @@ package com.limelight; import java.io.IOException; -<<<<<<< HEAD -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -======= + import java.net.SocketException; ->>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d import org.xmlpull.v1.XmlPullParserException; @@ -34,15 +29,13 @@ public class Connection extends Activity { private static final String DEFAULT_HOST = "192.168.1.240"; public static final String HOST_KEY = "hostText"; -<<<<<<< HEAD + @Override public void onResume() { super.onResume(); } -======= ->>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d @Override public void onPause() { SharedPreferences.Editor editor = prefs.edit(); @@ -64,41 +57,29 @@ public class Connection extends Activity { Log.v("NvmDNS", "onCreate"); - try { NvmDNS dns = new NvmDNS(); dns.execute(); - } catch (IOException e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } setContentView(R.layout.activity_connection); -<<<<<<< HEAD - // this.statusButton = (Button) findViewById(R.id.statusButton); - // this.hostText = (TextView) findViewById(R.id.hostTextView); -======= this.statusButton = (Button) findViewById(R.id.statusButton); this.pairButton = (Button) findViewById(R.id.pairButton); this.hostText = (TextView) findViewById(R.id.hostTextView); ->>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d + //prefs = getPreferences(0); //this.hostText.setText(prefs.getString(Connection.HOST_KEY, Connection.DEFAULT_HOST)); - /*this.statusButton.setOnClickListener(new OnClickListener() { + this.statusButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent(Connection.this, Game.class); intent.putExtra("host", Connection.this.hostText.getText().toString()); Connection.this.startActivity(intent); } -<<<<<<< HEAD - });*/ -======= }); this.pairButton.setOnClickListener(new OnClickListener() { @@ -154,7 +135,7 @@ public class Connection extends Activity { }).start(); } }); ->>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d + } } diff --git a/src/com/limelight/nvstream/NvComputer.java b/src/com/limelight/nvstream/NvComputer.java index 99d77431..e60ff5bf 100644 --- a/src/com/limelight/nvstream/NvComputer.java +++ b/src/com/limelight/nvstream/NvComputer.java @@ -1,8 +1,8 @@ package com.limelight.nvstream; import java.net.InetAddress; -import java.util.HashSet; import java.util.Locale; +import java.util.UUID; public class NvComputer { private String mDNSResponse; @@ -12,15 +12,14 @@ public class NvComputer { private int numOfApps; private String gpuType; private String mac; - private String uniqueID; + private UUID uniqueID; - private HashSet games; private int sessionID; private boolean paired; private boolean isBusy; - public NvComputer(String mDNSResponse, InetAddress ipAddress, String ipAddressString, int state, int numOfApps, String gpuType, String mac, String uniqueID) { + public NvComputer(String mDNSResponse, InetAddress ipAddress, String ipAddressString, int state, int numOfApps, String gpuType, String mac, UUID uniqueID) { this.mDNSResponse = mDNSResponse; this.ipAddress = ipAddress; this.ipAddressString = ipAddressString; @@ -29,8 +28,6 @@ public class NvComputer { this.gpuType = gpuType; this.mac = mac; this.uniqueID = uniqueID; - - this.games = new HashSet(); } public String getmDNSResponse() { @@ -46,7 +43,7 @@ public class NvComputer { } public String getIPAddressString() { - return this.ipAddress.getCanonicalHostName().toLowerCase(); + return this.ipAddress.getCanonicalHostName().toLowerCase(Locale.getDefault()); } public int getState() { @@ -65,18 +62,10 @@ public class NvComputer { return this.mac; } - public String getUniqueID() { + public UUID getUniqueID() { return this.uniqueID; } - - public boolean addGame(NvComputerGame game) { - return this.games.add(game); - } - public HashSet getGames() { - return this.games; - } - public void updateAfterPairQuery(int sessionID, boolean paired, boolean isBusy) { this.sessionID = sessionID; @@ -127,53 +116,10 @@ public class NvComputer { } public boolean equals(Object obj) { - NvComputer otherComputer = (NvComputer)obj; - if (this.ipAddress == null && otherComputer.getIpAddress() == null) { - return true; - } else if (this.ipAddress == null || otherComputer.getIpAddress() == null) { - return false; + if (obj instanceof UUID) { + return this.uniqueID.equals(obj); } else { - return this.ipAddress.equals(otherComputer.getIpAddress()); - } - } - - public class NvComputerGame { - private Integer ID; - private String appTitle; - private Boolean isRunning; - private Integer gameSession; - private Integer winLogon; - - public NvComputerGame(int ID, String appTitle, boolean isRunning) { - this.ID = ID; - this.appTitle = appTitle; - this.isRunning = isRunning; - } - - public void launchedGame(int gameSession, int winLogon) { - this.isRunning = true; - this.gameSession = gameSession; - this.winLogon = winLogon; - } - - public Integer getID() { - return this.ID; - } - - public String getAppTitle() { - return this.appTitle; - } - - public Boolean getIsRunning() { - return this.isRunning; - } - - public Integer getGameSession() { - return this.gameSession; - } - - public Integer winLogon() { - return this.winLogon; + return false; } } } \ No newline at end of file diff --git a/src/com/limelight/nvstream/NvmDNS.java b/src/com/limelight/nvstream/NvmDNS.java index 62892f52..5efd2f55 100644 --- a/src/com/limelight/nvstream/NvmDNS.java +++ b/src/com/limelight/nvstream/NvmDNS.java @@ -7,7 +7,11 @@ import java.net.InetAddress; import java.net.MulticastSocket; import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import org.xbill.DNS.DClass; import org.xbill.DNS.Header; @@ -15,214 +19,228 @@ import org.xbill.DNS.Message; import org.xbill.DNS.Name; import org.xbill.DNS.Record; import org.xbill.DNS.Section; +import org.xbill.DNS.TXTRecord; +import org.xbill.DNS.TextParseException; import org.xbill.DNS.Type; -import android.content.Context; -import android.net.nsd.NsdManager; -import android.net.nsd.NsdManager.DiscoveryListener; -import android.net.nsd.NsdManager.ResolveListener; -import android.net.nsd.NsdServiceInfo; import android.os.AsyncTask; import android.util.Log; -/** - * NvmDNS implements a clone of the NVidia Shield mDNS service for use on Limelight - * @author yetanothername - * - */ public class NvmDNS extends AsyncTask { - public static String NVSTREAM_MDNS_QUERY = "_nvstream._tcp.local."; - public static String NVSTREAM_MDNS_MULTICAST_GROUP = "224.0.0.251"; - public static InetAddress NVSTREAM_MDNS_MULTICAST_ADDRESS; - public static final short NVSTREAM_MDNS_PORT = 5353; + public static String MDNS_QUERY = "_nvstream._tcp.local."; + public static String MDNS_MULTICAST_GROUP = "224.0.0.251"; + public static InetAddress MDNS_MULTICAST_ADDRESS; + public static final short MDNS_PORT = 5353; - private HashSet nvstream_mdns_responses; - - private MulticastSocket nvstream_socket; + public static final int WAIT_MS = 5000; + + private HashSet responses; + private MulticastSocket socket; static { try { - NVSTREAM_MDNS_MULTICAST_ADDRESS = InetAddress.getByName(NvmDNS.NVSTREAM_MDNS_MULTICAST_GROUP); + MDNS_MULTICAST_ADDRESS = InetAddress.getByName(NvmDNS.MDNS_MULTICAST_GROUP); } catch (UnknownHostException e) { - NVSTREAM_MDNS_MULTICAST_ADDRESS = null; + MDNS_MULTICAST_ADDRESS = null; } } - - - /** - * We need to convert the IP Address into an IP Object - */ - static { - try { - NVSTREAM_MDNS_MULTICAST_ADDRESS = InetAddress.getByName(NvmDNS.NVSTREAM_MDNS_MULTICAST_GROUP); - } catch (UnknownHostException e) { - NVSTREAM_MDNS_MULTICAST_ADDRESS = null; - } - } - - /** - * This sets up the query sockets and the list, as well as sends out the query and listens for responses - * @throws IOException When shit breaks - */ - public NvmDNS() throws IOException { - Log.v("NvmDNS", "Constructor entered"); - this.nvstream_mdns_responses = new HashSet(); - Log.v("NvmDNS", "Constructor exited"); - } - private void makeFakeData() { + public NvmDNS() { + this.responses = new HashSet(); + + // Create our Socket Connection try { - this.nvstream_mdns_responses.add(new NvComputer("127.0.0.1", - InetAddress.getByName("127.0.0.1"), - InetAddress.getByName("127.0.0.1").getCanonicalHostName(), - 0, - 4, - "Intel(R) Extreme Graphics 3", - "DE:AD:BE:EF:CA:FE", - "foo")); - this.nvstream_mdns_responses.add(new NvComputer("10.0.2.15", - InetAddress.getByName("10.0.2.15"), - InetAddress.getByName("10.0.2.15").getCanonicalHostName(), - 0, - 5, - "Intel(R) Extreme Graphics 2", - "DE:AD:BE:EF:CA:FE", - "bar")); - } catch (Exception e) { - + this.socket = new MulticastSocket(NvmDNS.MDNS_PORT); + this.socket.setLoopbackMode(false); + this.socket.joinGroup(NvmDNS.MDNS_MULTICAST_ADDRESS); + Log.v("NvmDNS Socket Constructor", "Created mDNS listening socket"); + } catch (IOException e) { + Log.e("NvmDNS Socket Constructor", "There was an error creating the DNS socket."); + Log.e("NvmDNS Socket Constructor", e.getMessage()); } } - public void sendQueryAndWait() { - this.makeFakeData(); + public Set getComputers() { + return Collections.unmodifiableSet(this.responses); + } + + private void sendQuery() { + Header queryHeader = new Header(); + + // If we set the RA (Recursion Available) flag and our message ID to 0 + // then the packet matches the real mDNS query packet as displayed in Wireshark + queryHeader.setFlag(org.xbill.DNS.Flags.RA); + queryHeader.setID(0); + + Record question = null; try { - Log.v("NvmDNS UDP Loop", "mDNS Loop Started"); + // We need to create our "Question" DNS query that is a pointer record to + // the mDNS Query "Name" + question = Record.newRecord(new Name(NvmDNS.MDNS_QUERY), Type.PTR, DClass.IN); + } catch (TextParseException e) { + Log.e("NvmDNS Query", e.getMessage()); + return; + } - this.nvstream_socket = new MulticastSocket(NvmDNS.NVSTREAM_MDNS_PORT); - this.nvstream_socket.setLoopbackMode(false); - this.nvstream_socket.joinGroup(NvmDNS.NVSTREAM_MDNS_MULTICAST_ADDRESS); + // We combine our header and our question into a single message + Message query = new Message(); + query.setHeader(queryHeader); + query.addRecord(question, Section.QUESTION); - Log.v("NvmDNS UDP Loop", "Multicast Socket Created @" + this.nvstream_socket.getLocalPort()); + // Convert the message into Network Byte Order + byte[] wireQuery = query.toWire(); + Log.v("NvmDNS Query", query.toString()); + + // Convert our byte array into a Packet + DatagramPacket transmitPacket = new DatagramPacket(wireQuery, wireQuery.length); + transmitPacket.setAddress(NvmDNS.MDNS_MULTICAST_ADDRESS); + transmitPacket.setPort(NvmDNS.MDNS_PORT); - Header queryHeader = new Header(); - queryHeader.setFlag(org.xbill.DNS.Flags.RA); - queryHeader.setID(0); + // And (attempt) to send the packet + try { + Log.v("NvmDNS Query", "Blocking on this.nvstream_socket.send(transmitPacket)"); + this.socket.send(transmitPacket); + Log.v("NvmDNS Query", "Passed this.nvstream_socket.send(transmitPacket)"); + } catch (IOException e) { + Log.e("NvmDNS Query", "There was an error sending the DNS query."); + Log.e("NvmDNS Query", e.getMessage()); + } + } - Record question = Record.newRecord(new Name(NvmDNS.NVSTREAM_MDNS_QUERY), Type.PTR, DClass.IN); + public void waitForResponses() { + Log.v("NvmDNS Response", "mDNS Loop Started"); + + // We support up to 1500 byte packets + byte[] data = new byte[1500]; + DatagramPacket packet = new DatagramPacket(data, data.length); + + Message message = null; - Message query = new Message(); - query.setHeader(queryHeader); - query.addRecord(question, Section.QUESTION); - - byte[] wireQuery = query.toWire(); - - Log.v("NvmDNS UDP Loop", "Query: " + query.toString()); - - DatagramPacket transmitPacket = new DatagramPacket(wireQuery, wireQuery.length); - transmitPacket.setAddress(NvmDNS.NVSTREAM_MDNS_MULTICAST_ADDRESS); - transmitPacket.setPort(NvmDNS.NVSTREAM_MDNS_PORT); - - - - this.nvstream_socket.send(transmitPacket); - Log.v("NvmDNS UDP Loop", "Query Sent"); - - byte[] data = new byte[1500]; - DatagramPacket packet = new DatagramPacket(data, data.length); - Message message = null; - - while (true) { - - Log.d("NvmDNS UDP Loop", "Blocking on this.nvstream_query_socket.recieve()"); - this.nvstream_socket.receive(packet); - Log.d("NvmDNS UDP Loop", "Blocking passed on this.nvstream_query_socket.recieve()"); - + while (!this.socket.isClosed()) { + // Attempt to receive a packet/response + try { + Log.d("NvmDNS Response", "Blocking on this.nvstream_query_socket.recieve()"); + this.socket.receive(packet); + Log.d("NvmDNS Response", "Blocking passed on this.nvstream_query_socket.recieve()"); message = new Message(packet.getData()); - Record[] responses = message.getSectionArray(Section.ADDITIONAL); - if (responses.length != 0 && message.getSectionArray(Section.ANSWER).length != 0 && - message.getSectionArray(Section.ANSWER)[0].getName().toString().equals(NvmDNS.NVSTREAM_MDNS_QUERY)) { - - Log.v("NvmDNS UDP Reply", "Got a packet from " + packet.getAddress().getCanonicalHostName()); - Log.v("NvmDNS UDP Reply", "Question: " + message.getSectionArray(Section.ANSWER)[0].getName().toString()); - Log.v("NvmDNS UDP Reply", "Response: " + responses[0].getName().toString()); + } catch (IOException e) { + if (this.socket.isClosed()) { + Log.e("NvmDNS Response", "The socket was closed on us. The timer must have been reached."); + return; + } else { + Log.e("NvmDNS Response", "There was an error receiving the response."); + Log.e("NvmDNS Response", e.getMessage()); + continue; + } + } + + // We really only care about the ADDITIONAL section (specifically the text records) + Record[] responses = message.getSectionArray(Section.ADDITIONAL); + + // We only want to process records that actually have a length, have an ANSWER + // section that has stuff in it and that the ANSWER to our query is what we sent + if (responses.length != 0 && + message.getSectionArray(Section.ANSWER).length != 0 && + message.getSectionArray(Section.ANSWER)[0].getName().toString().equals(NvmDNS.MDNS_QUERY)) { + + Log.v("NvmDNS Response", "Got a packet from " + packet.getAddress().getCanonicalHostName()); + Log.v("NvmDNS Response", "Question: " + message.getSectionArray(Section.ANSWER)[0].getName().toString()); + Log.v("NvmDNS Response", "Response: " + responses[0].getName().toString()); - String[] txtRecords = responses[0].rdataToString().split("\" \""); - - // No, but really, there has to be a better way of doing this... - txtRecords[0] = txtRecords[0].substring(1); - txtRecords[txtRecords.length - 1] = txtRecords[txtRecords.length - 1].split("\"")[0]; - - int state = -1; - int numOfApps = -1; - String gpuType = "Intel(R) Extreme Graphics 2"; - String mac = "DE:AD:BE:EF:CA:FE"; - String uniqueID = "4"; - - for (int i = 0; i < txtRecords.length; i++) { - if (i == 0) { - state = Integer.parseInt(txtRecords[i].split("=")[1]); - } else if (i == 1) { - numOfApps = Integer.parseInt(txtRecords[i].split("=")[1]); - } else if (i == 2) { - gpuType = txtRecords[i].split("=")[1]; - } else if (i == 3) { - mac = txtRecords[i].split("=")[1]; - } else if (i == 4) { - uniqueID = txtRecords[i].split("=")[1]; - } + // The DNS library we are using does not use inferred generics :( + + TXTRecord txtRecord = null; + + + for (Record record : responses) { + Log.v("NvmDNS Response", "We recieved a DNS repsonse with a " + record.getClass().getName() + " record."); + if (record instanceof TXTRecord) { + txtRecord = (TXTRecord)record; } - + } + + if (txtRecord == null) { + Log.e("NvmDNS Response", "We recieved a malformed DNS repsonse with no TXTRecord"); + continue; + } + + @SuppressWarnings("unchecked") + ArrayList txtRecordStringList = new ArrayList(txtRecord.getStrings()); + + if (txtRecordStringList.size() != 5) { + Log.e("NvmDNS Response", "We recieved a malformed DNS repsonse with the improper amount of TXTRecord Entries."); + continue; + } + + // The general format of the text records is: + // SERVICE_STATE=1 + // SERVICE_NUMOFAPPS=5 + // SERVICE_GPUTYPE=GeForce GTX 760 x2 + // SERVICE_MAC=DE:AD:BE:EF:CA:FE + // SERVICE_UNIQUEID={A Wild UUID Appeared!} + // Every single record I've seen so far has been in this format + try { + int serviceState = Integer.parseInt(txtRecordStringList.get(0).toString().split("=")[1]); + int numberOfApps = Integer.parseInt(txtRecordStringList.get(1).toString().split("=")[1]); + String gpuType = txtRecordStringList.get(2).toString().split("=")[1]; + String mac = txtRecordStringList.get(3).toString().split("=")[1]; + UUID uniqueID = UUID.fromString(txtRecordStringList.get(4).toString().split("=")[1]); + + // We need to resolve the hostname in this thread so that we can use it in the GUI packet.getAddress().getCanonicalHostName(); - NvComputer computer = new NvComputer(responses[0].getName().toString(), packet.getAddress(), packet.getAddress().getCanonicalHostName(), state, numOfApps, gpuType, mac, uniqueID); - this.nvstream_mdns_responses.add(computer); - Log.v("NvmDNS NvComputer", computer.toString()); + NvComputer computer = new NvComputer(responses[0].getName().toString(), packet.getAddress(), packet.getAddress().getCanonicalHostName(), serviceState, numberOfApps, gpuType, mac, uniqueID); + this.responses.add(computer); + } catch (ArrayIndexOutOfBoundsException e) { + Log.e("NvmDNS Response", "We recieved a malformed DNS repsonse."); } - } - } catch (Exception e) { - e.printStackTrace(); - } + } + } } - @Override - protected Void doInBackground(Void... thisParameterIsUseless) { - Log.v("NvmDNS", "doInBackground init"); + protected Void doInBackground(Void... thisParameterIsUseless) { + Log.v("NvmDNS ASync", "doInBackground entered"); + + this.sendQuery(); + + + // We want to run our wait thread for an amount of time then close the socket. new Thread(new Runnable() { @Override public void run() { - Log.v("NvmDNS 1000 mS Wait", "going to sleep"); + Log.v("NvmDNS Wait", "Going to sleep for " + NvmDNS.WAIT_MS + "ms"); try { - - Thread.sleep(5000); + Thread.sleep(NvmDNS.WAIT_MS); } catch (InterruptedException e) { - e.printStackTrace(); + Log.e("NvmDNS Wait", "Woke up from sleep before time."); + Log.e("NvmDNS Wait", e.getMessage()); } - Log.v("NvmDNS 1000 mS Wait", "waking from sleep"); - NvmDNS.this.nvstream_socket.close(); - NvmDNS.this.nvstream_socket = null; - Log.v("NvmDNS 1000 mS Wait", "socket closed"); + Log.v("NvmDNS Wait", "Woke up from sleep"); + NvmDNS.this.socket.close(); + Log.v("NvmDNS Wait", "Socket Closed"); } }).start(); + - this.sendQueryAndWait(); - Log.v("NvmDNS", "doInBackground return"); + this.waitForResponses(); + + Log.v("NvmDNS ASync", "doInBackground exit"); return null; } @Override protected void onProgressUpdate(Integer... progress) { - Log.v("NvmDNS", "onProgressUpdate "); + Log.v("NvmDNS ASync", "onProgressUpdate"); } @Override protected void onPostExecute(Void moreUselessParameters) { - Log.v("NvmDNS", "onPostExecute"); - for (NvComputer computer : this.nvstream_mdns_responses) { - Log.i("NvmDNS NvComputer Printout", computer.toString()); + Log.v("NvmDNS ASync", "onPostExecute"); + for (NvComputer computer : this.responses) { + Log.i("NvmDNS NvComputer", computer.toString()); } - } }