Connectex: Error connecting to a physical device - go

I am trying to communicate with a device (connected using ethernet) using TCP/IP connection. When a connection request is sent, I am getting an error:
dial tcp 192.168.137.10:502: connectex: A connection attempt failed because
the connected party did not properly respond after a period of time,
or established connection failed because connected host has failed to respond
But if I am connecting to the simulator (which will act as device), it is getting connected and sending me response.
I am using GO for coding. This is my code to connect to device
conn, err := net.Dial("tcp", "192.168.137.10:502")
if err != nil {
return nil, err
} else {
return conn, nil
}
Hardware Info:
Windows 10, 64 bit machine
PLC device connected over TCP/IP

I suspect that there is a problem with the server and not your client code. The fact that you aren't just getting a "connection refused" error tells me that the remote port is probably open. Chances are that the server is not performing an accept() on the incoming connection within a reasonable time.
Things that might cause this
Maximum number of connection configured on the server has been exceeded or the service is too busy.
Server has crashed
Funny firewall or another routing issue between you and the server. Some deep packet inspection firewalls sometimes cause these types of issues.
I suggest you try and do troubleshooting on the server side.

Related

Can't build TCP connection with peers to send handshake message in golang, Bittorrent client

I am trying to build a bittorrent client. I wrote this function to verify that I can establish connection to send messages to other peers but its not working.
func handShake(torrent *gotorrentparser.Torrent, peer Peer, peedId []byte) {
conn,err := net.Dial("tcp", peer.ip + ":" + strconv.Itoa(int(peer.port)))
if err != nil {
panic(err)
}
defer conn.Close()
}
Here peer is a struct of string ip and uint16 port.
Getting the following error:
panic: dial tcp 152.57.73.47:27569: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
Couldn't find any similar issues. I tried to fix my local port address to be same as what I used to send the announce request but that didn't work either.
Edit: I tried with a different torrent, it is failing for some peers, but now it is working for some other peers. Is the issue only when the peer is using utorrent as bittorrent clients?
If you're developing a bittorrent client you should start with a more reproducable setup such as running an existing client with a known infohash on your local machine and then connecting to that (without using a tracker). Once you got that to work you can work on a tracker client implementation and then put those pieces together.
The internet is unreliable and bittorrent consists of many moving parts, so a single connection failure won't tell you much, you'll have to ensure that each part works properly and try with torrents that you have tested in an existing client to narrow down the cause of problems.
After few days here is the problem that I found.
Not all peers are able to accept an inbound request as they are behind a NAT.
Even when I hosted a torrent from one of my computer and tried to download through another system, I couldn't download as there was no reply from the peer for the SYN message being sent.
I was only able to download, when both the clients were on the same network and local peer discovery was enabled, and the TCP connection was also build with the local IP address.

Check for server reachability in Golang conn.Write

I am working on an application that tries to send some data to a remote server. Once I get the hostname, I get a connection by resolving the hostname using net.Dialer.DialContext. Once, I resolve the hostname, I keep on using conn.Write method to write data to the connection.
conn, err := d.DialContext(ctx, string(transport), addr)
_, err := client.conn.Write([]byte(msg))
Error faced: I observed that due to some issues, I was not able to ping my server. Surprisingly, conn obtained from DialContext did not complain while doing conn.Write and it kept writing to the same connection.
Can someone help me in how to modify my writing methods in order to get an error in case the destination server is not reachable?
From this UDP connection example
the best a "connected" UDP socket can do to simulate a send failure is to save the ICMP response, and return it as an error on the next write.
So try and (for testing) make a second conn.Write, to confirm that you would indeed get an error this time.

How do I connect to a Cassandra cluster deployed on AWS with gocql?

I have done a setup of a three node Cassandra cluster. This one is on aws, and the server port are open. The three servers are well connected to each other and work perfectly.
I have set
authenticator: AllowAllAuthenticator
in my cassandra.yaml file
I would like to make the connection with go cql, here is the connection code
cluster := gocql.NewCluster("x.xxx.xxx.xxx")
cluster.Keyspace = "keyspace_name"
cluster.Consistency = gocql.Quorum
cluster.ProtoVersion = 4
cluster.ConnectTimeout = time.Second * 10
session, err := cluster.CreateSession()
if err != nil {
fmt.Println(err)
}
but go cql sends me back this message.
2020/09/26 09:53:44 gocql: unable to dial control conn x.xxx.xxx: dial tcp 127.0.0.1:9042: connectex: No connections could be made because the target machine actively refused them.
2020/09/26 09:53:44 gocql: unable to create session: control: unable to connect to initial hosts: dial tcp x.xxx.xxx.xxx:9042: connectex: No connections could be made because the target machine actively refused them.
panic: runtime error: invalid memory address or nil pointer dereference
There's a good chance that you're using the private IP address in your app to connect to the nodes but those are not accessible remotely because by definition, they are private addresses.
You need to make sure that you've configured your nodes to use:
listen_address: <ec2_private_ip>
rpc_address: <ec2_public_ip>
Nodes communicate with each other using the listen_address whereas clients connect to the cluster using the rpc_address which is why it needs to be configured with the publicly-accessible IP addresses of the EC2 instances.
Once you've got the nodes configured correctly, configure your app to use the public IPs as contact points in:
cluster := gocql.NewCluster("public_ip1,public_ip2,...")
This should allow your app to connect to the cluster. Cheers!

Debug Connectivity Issue in gRPC Dial

I'm trying to make a gRPC connection to a server. In my client code (go version: go1.13 darwin/amd64), I have
conn, err = grpc.DialContext(ctx, c.tiProxyURL, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithBackoffMaxDelay(10*time.Second))
This blocks the code as the connection is for some reason not established. Is there any way to debug this further and figure out what is the issue with the connection?
The connection is established when I'm running the server code on my local machine, but is blocked when trying to connect to a service deployed in the cloud through the ingress URL.

What is the meaning of "ConnectEx tcp: The semaphore timeout period has expired."

I write a simple go program which runs on windows and tests whether the remote port is active:
package main
import (
"fmt"
"net"
)
func main(){
conn, err := net.Dial("tcp", "192.168.23.191:3403")
if err != nil {
fmt.Println(err)
} else {
conn.Close()
}
}
Now, the remote port is closed. I run it first time, and the error is:
dial tcp 192.168.23.191:3403: ConnectEx tcp: The remote computer refused the network connection.
Then I continue to run it, the error is changed to:
dial tcp 192.168.23.191:3403: ConnectEx tcp: The semaphore timeout period has expired.
Why the Dial returns "ConnectEx tcp: The semaphore timeout period has expired."? And what is the meaning of this error?
The call to net.Dial() has a timeout which expired.
As seen here, the Dialer struct has a Timeout field which defines the maximum amount of time that a Dial() will wait for a connect to complete.
net.Dial (with some intermediate functions) ends up calling ConnectEx, a Windows specific extension to BSD Sockets.
If the connection cannot be established (Windows conforms to RFC 1122 Section 4.2.3.5 and tries multiple times) ConnectEx fails with ERROR_SEM_TIMEOUT (AFAIK that isn't officially documented, one would expect an error like WSAETIMEDOUT).
So that error means that the port is closed.
On Windows 8 and newer Versions of Windows it is possible to change the connections settings for a single socket, if you want to do this in Go you have to do the version check and calls for yourself.

Resources