Client cannot reply ACK after receiving Server's SYN/ACK in virtual network interface environment - c++

I'm setting a local vpn environment, and I want to capture traffic locally through virtual network interface then forwarding them to real destinations through a physical network interface binding socket. However, I cannot even connect real destination after setting up a tun virtual network interface.
My testing machine:
Linux testing-VirtualBox 3.19.0-15-generic #15-Ubuntu SMP Thu Apr 16 23:32:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
First I successfully create a virtual network interface named tun0 as below:
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.2.1 P-t-P:192.168.2.1 Mask:255.0.0.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
For brevity, I just add the target server's ip address into route table:
route add -host 45.113.192.102 dev tun0
The route table is as below:
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 xxx.xx.xxx.xxx 0.0.0.0 UG 0 0 0 eth0
45.113.192.102 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
xxx.xx.xxx.xxx 0.0.0.0 255.255.255.128 U 0 0 0 eth0
192.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 tun0
xxx.xx.xxx.xxx is my internal host/gateway ip address.
At last, I create a socket and bind the socket into physical network interface. I use libuv here and should no matter to the issue.
struct sockaddr_in remote_addr;
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = ntohs(443);
inet_pton(AF_INET, "45.113.192.102", &remote_addr.sin_addr);
uv_os_sock_t sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
std::cout << "ERROR--- create socket failed\n";
return -1;
}
int32_t r;
r = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "eth0", strlen("eth0"));
if (r != 0) {
std::cout << "setsockopt failed: " << errno;
return -1;
}
uv_tcp_init(g_uv_loop, &socket_handle);
r = uv_tcp_open(&socket_handle, sock);
uv_connect_t connect_req;
r = uv_tcp_connect(&connect_req, &socket_handle,
(struct sockaddr *) &remote_addr, _tcp_connect_cb);
I run my code and found I cannot connect to "45.113.192.102".
I capture the traffic through wireshark and found that my program has sent SYN to "45.113.192.102", and "45.113.192.102" also replied SYN,ACK. However, after that seems my program did not send ACK, which causes connecting failed.
In the following, Client continuously sends [TCP Spurious Retransmission] SYN and Server replys [TCP Retransmission] SYN,ACK.

Related

ESP8266 NodeMCU Lua "Socket client" to "Python Server" connection not possible

I was trying to connect a NodeMCU Socket client program to a Python server program, but I was not able to establish a connection.
I tested a simple Python client server code and it worked well.
Python Server Code
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
print c.recv(1024)
c.send('Thank you for connecting')
c.close() # Close the connection
Python client code (with this I tested the above code)
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.connect((host, port))
s.send('Hi i am aslam')
print s.recv(1024)
s.close # Close the socket when done
The output server side was
Got connection from ('192.168.99.1', 65385)
Hi i am aslam
NodeMCU code
--set wifi as station
print("Setting up WIFI...")
wifi.setmode(wifi.STATION)
--modify according your wireless router settings
wifi.sta.config("xxx", "xxx")
wifi.sta.connect()
function postThingSpeak()
print("hi")
srv = net.createConnection(net.TCP, 0)
srv:on("receive", function(sck, c) print(c) end)
srv:connect(12345, "192.168.0.104")
srv:on("connection", function(sck, c)
print("Wait for connection before sending.")
sck:send("hi how r u")
end)
end
tmr.alarm(1, 1000, 1, function()
if wifi.sta.getip() == nil then
print("Waiting for IP address...")
else
tmr.stop(1)
print("WiFi connection established, IP address: " .. wifi.sta.getip())
print("You have 3 seconds to abort")
print("Waiting...")
tmr.alarm(0, 3000, 0, postThingSpeak)
end
end)
But when I run the NodeMCU there is no response in the Python server.
The Output in the ESPlorer console looks like
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
WiFi connection established, IP address: 192.168.0.103
You have 3 seconds to abort
Waiting...
hi
Am I doing something wrong or missing some steps here?
Your guidance is appreciated.
After I revisited this for the second time it finally clicked. I must have scanned your Lua code too quickly the first time.
You need to set up all event handlers (srv:on) before you establish the connection. They may not fire otherwise - depending on how quickly the connection is established.
srv = net.createConnection(net.TCP, 0)
srv:on("receive", function(sck, c) print(c) end)
srv:on("connection", function(sck)
print("Wait for connection before sending.")
sck:send("hi how r u")
end)
srv:connect(12345,"192.168.0.104")
The example in our API documentation is wrong but it's already fixed in the dev branch.

Pysnmp openServerMode with IPv6

I try to start a SNMP Agent with pysnmp.
for IPv4 and IPv6 bind, it works pretty fine with localhost ('127.0.0.1' and '::1')
but when I try to use other IPv6 IP which I fetched from interface, it failed due to
[vagrant#test SOURCES]$ sudo python snmp_agent.py enp0s8
Traceback (most recent call last):
File "snmp_agent.py", line 172, in <module>
master_agent_startup(ifname=sys.argv[1])
File "snmp_agent.py", line 101, in master_agent_startup
(get_ipv6_address(interface_name), SNMP_AGENT_PORT))
File "/usr/lib/python2.7/site-packages/pysnmp/carrier/asyncore/dgram/base.py", line 50, in openServerMode
raise error.CarrierError('bind() for %s failed: %s' % (iface, sys.exc_info()[1],))
pysnmp.carrier.error.CarrierError: bind() for ('fe80::a00:27ff:fe9e:9c16', 8001) failed: [Errno 22] Invalid argument
This is the output from the interface 'enp0s8':
[vagrant#test SOURCES]$ ifconfig enp0s8
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.20.20.26 netmask 255.255.255.0 broadcast 172.20.20.255
inet6 fe80::a00:27ff:fe9e:9c16 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:9e:9c:16 txqueuelen 1000 (Ethernet)
RX packets 874053 bytes 115842841 (110.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 862314 bytes 114652475 (109.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
This is the code piece I used for IPv6 bind:
def get_ipv6_address(ifname):
return netifaces.ifaddresses(ifname)[netifaces.AF_INET6][0]['addr'].split('%')[0]
config.addSocketTransport(snmpEngine, udp.domainName,
udp.UdpTransport().openServerMode(
(get_ipv4_address(interface_name), SNMP_AGENT_PORT))
)
config.addSocketTransport(snmpEngine, udp6.domainName,
udp6.Udp6SocketTransport().openServerMode(
(get_ipv6_address(interface_name), SNMP_AGENT_PORT))
)
From pysnmp sample, it seems the parameter inside "openServerMode()" is just a tuple of IP and port.
And from output error I suppose there is no error for given IP and port.
so why it failed due to Invalid argument?
Could you #Ilya Etingof or some other pysnmp expert help me with it?
Thanks.
UPDATE: I try to bind it with given suggestion, but is still doesn't work.
the bind command was run from a new installed CentOS. but it still failed:
[root#test ~]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.10.20.4 netmask 255.255.255.0 broadcast 10.10.20.255
inet6 fe80::f816:3eff:fee1:5475 prefixlen 64 scopeid 0x20<link>
ether fa:16:3e:e1:54:75 txqueuelen 1000 (Ethernet)
RX packets 12242 bytes 962552 (939.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12196 bytes 957826 (935.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root#test ~]# python
Python 2.7.5 (default, Oct 11 2015, 17:47:16)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, 0)
>>> addr_and_port = ('fe80::f816:3eff:fedb:ba4f', 8001)
>>> s.bind(addr_and_port)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 22] Invalid argument
>>>
[1]+ Stopped python
[root#test ~]# netstat -anp | grep 8001
[root#test ~]#
One more update:
I suppose the bind is failed due to my environment has some issue with IPv6 configuration. As I'm only able to get one IPv4 address by using "socket.getaddrinfo()" method.
Br,
-Dapeng Jiao
You could get this error if attempted to bind the same socket more than once. But I can't see that is the case in your code.
That .openServerMode() method does no magic -- it just calls .bind() on socket object. For inspiration, does this work in at your Python prompt?
from pysnmp.carrier.asyncore.dgram import udp6
addr_and_port = ('fe80::a00:27ff:fe9e:9c16', 8001)
udp6.Udp6SocketTransport().openServerMode(addr_and_port)
or even:
import socket
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, 0)
addr_and_port = ('fe80::a00:27ff:fe9e:9c16', 8001)
s.bind(addr_and_port)
My hope is that tests like these may help you figuring out the problem...
When you use an IPv6 link-local address, you must always use the scope along with it. The link-local address is not valid without its scope, thus you will receive an Invalid argument error.
For example, instead of using fe80::a00:27ff:fe9e:9c16 you must use fe80::a00:27ff:fe9e:9c16%enp0s8.

UDP broadcasting with QT

I'm searching since two days how to sent a UDP broadcast. I have seen many examples (also the broadcastReceiver and broadcastSender on the qt web site) but they are still not working for me. When I try to send a broadcast, the method QUdpSocket::writeDatagram(..) returns -1 and the datas are not transmitted. I'm on ubuntu 14.04 x64. I wish to know if there is a particular manipulation that I should do to make this broadcast work. Thanks and sorry for my english level.
that is my code
envoyeurUDP=new QUdpSocket(this);
recepteurUDP=new QUdpSocket(this);
//démarrage du serveur pour UDP
if (!recepteurUDP->bind(QHostAddress::AnyIPv4,7878,QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
qDebug("Impossible de créer la socket en écoute");
exit(EXIT_FAILURE);
}
connect(recepteurUDP, SIGNAL(readyRead()), this, SLOT(lireDatagrams()));
void FileTransferManager::lireDatagrams(){
char* donnees;
while (recepteurUDP->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(recepteurUDP->pendingDatagramSize());
recepteurUDP->readDatagram(datagram.data(), datagram.size());
donnees=datagram.data();
}}
and this one to send datagrams
void FileTransferManager::sendDatagram(string msg, QHostAddress addr){
QByteArray datagram=msg.data();
qint64 r=envoyeurUDP->writeDatagram(datagram.data(), datagram.size(), addr, 7878);}
and i use it like this :
fileManager.sendDatagram("blabla",QHostAddress::Broadcast);
here is the output of my ifconfig command:
eth0 Link encap:Ethernet HWaddr f8:a9:63:2d:89:ff
UP BROADCAST MULTICAST MTU:1500 Metric:1
Packets reçus:0 erreurs:0 :0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 lg file transmission:1000
Octets reçus:0 (0.0 B) Octets transmis:0 (0.0 B)
lo Link encap:Boucle locale
inet adr:127.0.0.1 Masque:255.0.0.0
adr inet6: ::1/128 Scope:Hôte
UP LOOPBACK RUNNING MTU:65536 Metric:1
Packets reçus:5311 erreurs:0 :0 overruns:0 frame:0
TX packets:5311 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 lg file transmission:0
Octets reçus:661728 (661.7 KB) Octets transmis:661728 (661.7 KB)
wlan0 Link encap:Ethernet HWaddr b8:ee:65:ab:4f:77
inet adr:10.42.0.1 Bcast:10.42.0.255 Masque:255.255.255.0
adr inet6: fe80::baee:65ff:feab:4f77/64 Scope:Lien
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Packets reçus:14069 erreurs:0 :0 overruns:0 frame:0
TX packets:15529 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 lg file transmission:1000
Octets reçus:6007592 (6.0 MB) Octets transmis:2307422 (2.3 MB)
I know this is old, but this works for me on Ubuntu 16.04 LTS to broadcast messages to any listener:
QUdpSocket *udp = new UdpSocket(this);
QByteArray dgram = "hello";
udp->writeDatagram(dgram.data(), dgram.size(), QHostAddress::Broadcast, ipPort);

icecast cannot find MPD mountpoint

I have setup icecast 2 server and mpd too.
Both are working fine individually but icecast doesn't show the mpd in the mount list.
Here is my mpd.conf
# See: /usr/share/doc/mpd/mpdconf.example
user "ayush"
pid_file "~/.mpd/mpd.pid"
db_file "~/.mpd/mpd.db"
state_file "~/.mpd/mpdstate"
log_file "~/.mpd/mpd.log"
playlist_directory "~/.mpd/playlists"
music_directory "~/Music"
audio_output {
type "shout"
encoding "ogg"
name "stream"
host "localhost"
port "8000"
mount "/mpd.ogg"
bind_to_address "127.0.0.1"
# This is the source password in icecast.xml
password "pass"
# Set either quality or bit rate
# quality "5.0"
bitrate "128"
format "44100:16:2"
# Optional Parameters
user "source"
# description "here is my long description"
# genre "jazz"
} # end of audio_output
# Need this so that mpd still works if icecast is not running
audio_output {
type "alsa"
name "fake out"
driver "null"
}
Also here is the output of my netstat
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 315/sshd
tcp 0 0 0.0.0.0:17500 0.0.0.0:* LISTEN 651/dropbox
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 8006/icecast
tcp 0 0 0.0.0.0:16001 0.0.0.0:* LISTEN 1211/pulseaudio
tcp 0 0 0.0.0.0:57253 0.0.0.0:* LISTEN 1211/pulseaudio
tcp 0 0 0.0.0.0:60421 0.0.0.0:* LISTEN 1211/pulseaudio
tcp 0 0 0.0.0.0:4713 0.0.0.0:* LISTEN 1211/pulseaudio
tcp6 0 0 :::22 :::* LISTEN 315/sshd
tcp6 0 0 :::16001 :::* LISTEN 1211/pulseaudio
tcp6 0 0 :::36418 :::* LISTEN 1211/pulseaudio
tcp6 0 0 :::32899 :::* LISTEN 1211/pulseaudio
tcp6 0 0 :::6600 :::* LISTEN 8046/mpd
tcp6 0 0 :::4713 :::* LISTEN 1211/pulseaudio
My guess is that because mpd is not listening on ipv4 icecast is not able to see the mount point.
But I also don't understand why it doesn;t listen on ipv4 when I have explicitly used bind_to_address option.
Can someone please tell me how to make icecast see the mpd mountpoint.
Thanks
I was having the same issue and it seemed to stem from the setting bitrate "128" in mpd.conf. I was able to get the mountpoint to show up when I used quality "5.0".
I also tried bitrate "320" which did not work either, however I was able to see the mount with quality "10.0" as well. From this it seems that only the quality setting works.
I am not entirely sure, but I believe this stems from the way Vorbis is encoded. It seems like the encoders accept flags for quality in the form of -q {quality} where {quality} is any value from 0.0 to 10.0 (including factional values).
Sources:
https://en.wikipedia.org/wiki/Vorbis
http://linux.die.net/man/1/oggenc
I don't any problems connecting to icecast using the same settings, the only difference I see is the bind_to_address. This is used for connecting mpd clients if I'm not mistaken and not for the streaming server. It doesn't belong under audio_output.
Also, is there something in the MPD logs?

How can you force a web service client to use a specific port?

Is it possible to force an web service client to talk from a specific range of port E.g. 4900- 4999 to a web server in port 80?
I understand now that there is client and server port numbers and need to create a client application to send http statuses to a web server but firewall team only opens ports 4900 to 4999 in the client.
Any ideas?
If you are using a web browser to connect to your server then you may be out of luck but as you said in your question that you are creating a client application you can do this with the bind system call in both Windows and Linux (this code is in C):
struct sockaddr_in client;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
memset(&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_addr.s_addr = htonl(INADDR_ANY);
client.sin_port = htons(4901);
Then call bind:
res = bind(sock, (struct sockaddr *)&client, sizeof(client));
If this call is successful (res is 0) you can then connect your socket to the server and you will be connecting from port 4901.
In case someone else needs it, here is the Python code to do that:
#!/usr/bin/env python
from socket import *
import time
HOST = '**.**.**.**' # IP of the server
PORT = 8080
GET = '/hello/There'
BUFSIZ = 1024
ADDR = (HOST, PORT)
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(('',4925))
sock.connect(ADDR)
print 'connected'
request = """GET %s HTTP/1.0\n
Host: %s\n
User-Agent: Python\n
\n""" % (GET, HOST)
sock.send(request)
data = sock.recv(1024)
string = ""
while len(data):
string = string + data
data = sock.recv(1024)
print string
sock.close()
This is working with a wsgi server running on the other side. Pretty straight forward. Thanks for the help.