Very strange behavior...
I have 3 machines:
----------- ------------ -----------
| A (x86) |-----| B (x86) |-----| C (arm) |
| sender | | receiver | | sender |
----------- ------------ -----------
A and B are Linux (Ubuntu 12.04) machines, kernel 3.2;
C is an android (ICS) machine, kernel 3.0.8;
All are connected via RJ45 cables;
Connections are OK, network is set up correctly;
Issue is: when machine C (ARM-android) sends a UDP packet which payload size is over 1472 bytes (maximum payload before packet gets fragmented), server application on machine B is never able to receive it, ... regarding that:
Source/Dest IP addresses are correct: I can receive all the datagrams I send if I set the payload size less or equal to 1472;
On machine B (receiver), if I dump network traffic with Wireshark, I can see each fragment, and then re-assembled message => from Wireshark point of view, it's all good!
Comparing each fragment header as well as re-assembled message with what I can dump when the same message is sent from machine A (which is always received OK), everything seems perfect (only differences are IP addresses, and checksum, since UDP header checksum takes in account IP address fields).
There is no MTU issue, packets are fragmented as expected.
There is no router/switch between the machines
ifconfig shows neither packets drop, nor overflows, nor any other classical error!
... this is so weird!!
I've spent some time on Internet, but never found any topic like this one. Each time people has troubles with UDP, either their MTU discovery was not correct, or they did some mishandling in the testing procedure, or they could not dump message on receiver host, ... this is not the case here!!
For sure, I know issue is on sender end (machine C), but maybe is could be easier to enable some logs (at kernel level?) on receiver end to understand why UDP datagram disappears!? Any advice? Are there specific files I could check in /proc/sys/net, or kernel options I should enable?
Thanks a lot.
If your machines are indeed connected as depicted, i.e. they are not connected to switch/hub, then you must have two NICs on B therefore they will have different addresses so the address you use to send to B from A will not be the same as sending to B from C. i.e.
Could the address you are sending to be wrong? Though that would not explain how smaller datagrams get through - are you sure they are?
Note: Theses addresses would have to be assigned manually as you are not connected to DHCP, furthermore these addresses will need to be in the same subnet as A and C. Are all your addresses (A, BA, BC and C) in the same subnet? What address:port is the socket on B bound to and listening on? Does B continue to receive after receiving a datagram? Please provdie some code..
OR, even if your machines are connected to a switch/hub,, is the "Don't fragment" bit set on datagrams sent from C which would explain why larger ones are dropped but not smaller ones.
Related
My goal is to send a UDP message (smaller than 100 bytes) from a SmartWatch (running wear os 2) to an Arduino on the same network. As long as the SmartWatch stays connected to the wifi (ip address of the watch: 145.167.189.23) this works great.
But when I turn on bluetooth, the SmartWatch disables wifi and switches to an internet connection via the bluetooth connected phone.
The SmartWatch gets an ip address in a subnet of the internet connection from the mobile (if the mobile has the ip address 145.167.189.105, it gets 145.167.177.4). TCP requests, like 'stackoverflow.com' work fine.
If I now try to send a UDP message nothing arrives at the Arduino.
I already tried to send a UDP message to 255.255.255.255, 145.255.255.255, 145.167.255.255, 145.167.189.255, but nothing ever arrived at the Arduino ( verified by Wireshark).
Over six years ago there was the same problem (Simple UDP Broadcast not working on Android Wear), at that time wear os 2 was not available. The only proposed solution was the 'Wear Data Layer'. I already tried this as well, but observed very large latencies (about 3 seconds). Therefore, these do not represent a solution for me at all.
The documentation for network access on wear os only says
You can use protocols such as HTTP, TCP, and UDP
Maybe someone could give me a hint why the UDP messages are not forwarded from the phone.
Only DNS udp packages can be forwarded to the phone.
It setup some iptable rules to forward udp packages to the TPROXY. Look at the following rules (iptables -t mangle -L). It does't forward udp packges to Reserved IP addresses.
Chain oem_CW_PROXY_UDP (22 references)
target prot opt source destination
RETURN all -- anywhere 0.0.0.0/8
RETURN all -- anywhere loaclhost/8
RETURN all -- anywhere 100.64.0.0/10
RETURN all -- anywhere 127.0.0.0/8
RETURN all -- anywhere 169.254.0.0/16
RETURN all -- anywhere 172.16.0.0/12
RETURN all -- anywhere 192.0.0.0/29
RETURN all -- anywhere 192.0.2.0/24
RETURN all -- anywhere 192.168.0.0/16
RETURN all -- anywhere 198.18.0.0/15
RETURN all -- anywhere 198.51.100.0/24
RETURN all -- anywhere 203.0.113.0/24
RETURN all -- anywhere 224.0.0.0/4
RETURN all -- anywhere 240.0.0.0/4
RETURN all -- anywhere 255.255.255.255
TPROXY udp -- anywhere anywhere TPROXY redirect 0.0.0.0:35070 mark 0x1/0x1
The TPROXY will forward the reveived udp packcages to the phone throught bluetooth socket. But it will only forwoard DNS packages, which can be seen from the watch's logcat.
It seems that Wear OS decided to only forwoard DNS packages at some time.
05-20 12:20:31.269806 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 47 bytes, from: /192.168.167.239:36215 original dst: /8.8.8.8:53
05-20 12:21:05.264492 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 47 bytes, from: /192.168.167.239:63348 original dst: /8.8.8.8:53
05-20 12:21:05.272685 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 32 bytes, from: /192.168.167.239:34219 original dst: /8.8.8.8:53
05-20 12:21:38.282089 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 47 bytes, from: /192.168.167.239:54529 original dst: /8.8.8.8:53
05-20 12:21:38.287255 1263 5866 D HOME : [ClockworkProxyUdp]Got packet with 32 bytes, from: /192.168.167.239:58688 original dst: /8.8.8.8:53
We want to build a simple data sharing application where 2 Android mobiles (or computers) connected on any internet (wifi/network) upload and download their data to the server through HTTPS.
e.g. A wants to send data to B. A will trigger a "put" like HTTPS API and upload the data to the bucket of B. B will call the "get" like HTTPS API and download its content.
Now the issue is that the communication between A and B is demand based. It can happen after minutes, hours or days. If we go with HTTPS way, then we will have to keep B in a long polling to server which will eat out the resources for days when there is no message. If we poll every minute or 2 then the communication will not happen in near real time.
To counter this problem, we have come up with following idea:
Whenever mobile registers to internet, it creates a UDP port and
binds to it
It makes 1 time HTTPS connection to server and sends its IP
address and port
There can be optional dummy data exchange between server and client
using UDP (to and from)
After this client doesn't have any active connection and remains
on the same internet; It continuously waits on the UDP
port for data to be received; If internet changes then again
repeat from step-1
When data is received for the given client, then server sends
some predefined dummy UDP data to client as a wake up call. This
data is continuously sent until the client bucket is read via HTTPS
Upon identifying the data received on UDP, client makes an HTTPS
connection to server and reads its intended data from its bucket and
closes; Server identifies this and stops UDP
In theory this solution looks fine. But from internet I came across following problems for which I will require answers:
What kind of IP address and port should be sent to server from
client? Is it the ISP/network provided IP or something else?
How server would identify the exact client to send some UDP data?
e.g. if 2 mobiles on the same internet have same IP and ports
In C socket library, there are 2 ways of UDP connections: (1)
connect() and then just send()/recv() (2) Directly
sendto()/recvfrom() using IP addresses. Which should be used in
this scenario?
Besides above question, any improvement on the actual way of "push notification" described above is welcome.
You need to take care of clients behind NAT, for that you can use UDP Hole Punching.
Let A and B be the two hosts, each in its own private network; NA and
NB are the two NAT devices with globally reachable IP addresses EIPA
and EIPB respectively; S is a public server with a well-known globally
reachable IP address.
A and B each begin a UDP conversation with S; the NAT devices NA and NB create UDP translation states and assign
temporary external port numbers EPA and EPB
S examines the UDP packets
to get the source port used by NA and NB (the external NAT ports EPA
and EPB)
S passes EIPA:EPA to B and EIPB:EPB to A
A sends a packet to
EIPB:EPB.
NA examines A's packet and creates the following tuple in
its translation table: {Source-IP-A, EPA, EIPB, EPB}
B sends a packet
to EIPA:EPA
NB examines B's packet and creates the following tuple in
its translation table: {Source-IP-B, EPB, EIPA, EPA}
Depending on the
state of NA's translation table when B's first packet arrives (i.e.
whether the tuple {Source-IP-A, EPA, EIPB, EPB} has been created by
the time of arrival of B's first packet), B's first packet is dropped
(no entry in translation table) or passed (entry in translation table
has been made).
Depending on the state of NB's translation table when
A's first packet arrives (i.e. whether the tuple {Source-IP-B, EPB,
EIPA, EPA} has been created by the time of arrival of A's first
packet), A's first packet is dropped (no entry in translation table)
or passed (entry in translation table has been made).
At worst, the
second packet from A reaches B; at worst the second packet from B
reaches A. Holes have been "punched" in the NAT and both hosts can
communicate.
I want to discover all Android devices IP and Port in same wifi network using ZeroMQ?
My app basically connect all device in same wifi network (no internet needed) and message to each other. Once ip and port I know I am send message successfully but how to know all device internet Protocol (ip) Using ZeroMQ?
Principle
Part A)
Every IEEE 802.x CSMA/CD network "collision domain" ( wifi AP/SSID is such one ) has to be managed so as to work well. Thus the Address Resolution Protocol [ARP] will help you in the task to find all ISO-OSI-Layer-3 IP Addresses. Wifi Access Point [AP] host, to which all live devices register and handshake with, is the choice to start with.
HG520i> ip arp status
received 54205 badtype 0 bogus addr 0 reqst in 12105 replies 196 reqst out 14301
cache hit 63152696 (24%), cache miss 19455672 (23%)
IP-addr Type Time Addr stat iface
192.168.0.230 10 Mb Ethernet 290 00:15:af:e6:b1:79 41 enif0
192.168.0.62 10 Mb Ethernet 300 00:0c:29:98:d4:3b 41 enif0
192.168.0.55 10 Mb Ethernet 300 00:27:0e:07:c5:9e 41 enif0
192.168.0.255 10 Mb Ethernet 0 ff:ff:ff:ff:ff:ff 43 NULL
num of arp entries= 4
Part B)
Scanning all the ports on all the known IP hosts is a dumb brute force approach to the second issue.
Scanning just a subset of "reasonable" ones would save you both the time and efforts on peer-recognitions.
Using some smarter, active "visibility self-advertisement policy" will save you even more.
Solution
Decide on multi-party system architecture, whether an individual passive scan, a central/distributed proxy-assisted scan or an active self-advertisement policy will be used to build and maintain live records in a neighbouring hosts register.
ZeroMQ per-se brings you a lot of power for the smart solutions, while the dumb-force solutions would have to wait till fully fledged ZeroMQ services will be ready. Low level L2/L3-inspections will have to bring their fruit before ZeroMQ can first .bind()/.connect()
Needless to say, that uncoordinated CSMA/CD networks do not guarantee that all the L2-visible hosts will have "compatible" L3-ip-adddress ( will belong to / have the same L3-ip-network address ).
Thus you never know about all IP addresses without a truly low-level sniffer.
I am using TCPDUMP-arm because I'd like to capture TCP packets arriving on my tablet. The problem is that I want to get rid of the results about the outgoing packets.
When I execute:
./tcpdump-arm tcp -qt -l > /sdcard/res.txt
I get results like:
IP 172.17.***.***.49890 > 74.125.***.***.5228: tcp 139
IP 172.17.***.***.56869 > 173.194.***.***.80: tcp 0
IP 173.194.***.***.80 > 172.17.***.***.56869: tcp 0
Where the IP starting with 172.17. is mine.
So, is there a way to adjust TCPDUMP to show me only the last result (the one where my IP is destination)
Not sure about tcpdump-arm (never used it), but assuming that the pcap-filter expression is the same as tcpdump's (which is quite likely, I'd think), then to see tcp traffic and leave out packets where your IP address is the source, your expression should be:
tcp and src host not 172.17.x.x
Can't try it out now to be 100% sure, but I'll leave that to you.
I've managed to deal with the problem :)
Also , I created one ToggleButton in my app , in order to Start/Stop TCPDUMP. Now I want to be able to read the text file which is generated, while the program is still executing , and make decisions based on the data from the file.
The problem is that I want to read only the latest results , and so far I can just read the whole file from begging to the end. My other option is somehow to read the output from TCPDUMP directly/live in my app , without making a text file , but I have no idea how to achieve that.
I am looking forward for your replies.
I am willing to create a server and client program on my android mobile devices.
The devices communicate with each other on the same wifi network, therefore, some simple scanning mechanism must be implemented - The client phones search for a server phone through some kind of broadcast.
What I did:
My protocol - the client phone broadcasts a message port p on the wifi, the server listens on port p. when the server gets the broadcast message it sends a message back, therefore discovering itself to the client.
My code -
I have opened a broadcast socket on my app, it sends a broadcast message.
Meanwhile there is a python script on my PC that listens and replies - I use python so that my testing will be easier - Wireshark on the PC and I can see everything.
What happens:
When I use one of my Galaxy S phones - it works and I get a response.
When I use the other Galaxy S phone - it doesn't work.
Now this is what I know:
The phone that works actually has Nexus ROM on it Ver. 4.1.1
The phone that doesn't work has 2.3.3 regular galaxy ROM
The python code says it receives both of the broadcasts sent from both phones, and replies to both of them without raising any exception.
So far I was thought the problem may be
1. the older version'd phone.
2. the windows firewall
3. the router firewall
So I have opened Wireshark, and Indeed I saw that both phones are sending their broadcasts - it was logged on Wireshark.
But the python script only responded to the first one.
So this is why 1 & 3 are irrelevant - if the router firewall was blocking my UDP I would have still seen the python server response, same with the older versioned phone.
To get rid of 2 i just disabled the windows firewall - still same problem.
Does anyone has a clue to why this effect might happen?
Thanks!
Edit
My python code:
def scan(data, addr, sock):
print "received scan message:", data, addr
name = u"name".encode("utf-16-le")
data = "DISC" + short2bytes(len(name)) + name
print "sending back %s to %s" % (data, addr)
sock.sendto(data, addr)
if __name__ == "__main__":
sock = socket(AF_INET, SOCK_DGRAM)
sock.bind(('', UDP_PORT))
while 1:
data, addr = sock.recvfrom(1500)
print "received packet " + data
if data.startswith("SCAN"):
scan(data, addr, sock)
edit 2:
Okay! Seems like my code and protocol DID work.
As it turns out the 2.3.3 phone had some severe ARP problems.
After some resets it works flawlessly!