PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label tcp. Show all posts
Showing posts with label tcp. Show all posts

Saturday, October 22, 2022

[FIXED] How can a socket connect when bound to a specific ethernet interface that's also being used by VPN / utun interface?

 October 22, 2022     macos, networking, routes, sockets, tcp     No comments   

Issue

I'm trying to write a function that can connect to a server using a specific network interface so that it's consistently routed through that interface's gateway. This is on a macOS system that has one or more VPN connections.

Here's a proof-of-concept test function I've written:

void connectionTest(const char *hostname, int portNumber, const char *interface) {
    struct hostent *serverHostname = gethostbyname(hostname);
    
    if (serverHostname == NULL) {
        printf("error: no such host\n");
        return;
    }

    int socketDesc = socket(AF_INET, SOCK_STREAM, 0);
    int interfaceIndex = if_nametoindex(interface);
    
    if (interfaceIndex == 0) {
        printf("Error: no such interface\n");
        close(socketDesc);
        return;
    }
    
    // Set the socket to specifically use the specified interface:
    setsockopt(socketDesc, IPPROTO_IP, IP_BOUND_IF, &interfaceIndex, sizeof(interfaceIndex));

    struct sockaddr_in servAddr;
    bzero((char *)&servAddr, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    bcopy((char *)serverHostname->h_addr, (char *)&servAddr.sin_addr.s_addr, serverHostname->h_length);
    servAddr.sin_port = htons(portNumber);

    if (connect(socketDesc, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
        printf("connect failed, errno: %d", errno);
        close(socketDesc);
        return;
    }
    
    printf("connection succeeded\n");
    close(socketDesc);
}

This function will successfully connect so long as the interface is one of the utun interfaces created by the VPNs, or a physical interface that is not used by the VPNs. But if I try to use the physical interface that is used by the VPNs, the function fails with errno 51: Network is unreachable.

For a more specific example, consider a system with the following network interfaces:

en0: Ethernet connection
en1: Wi-Fi connection
utun10: VPN connection 1, connected via en0
utun11: VPN connection 2, also connected via en0

If I call my function with something like:

connectionTest("api.ipify.org", 80, "en1");
connectionTest("api.ipify.org", 80, "utun10");
connectionTest("api.ipify.org", 80, "utun11");

... it will succeed. However, this is what produces the "network unreachable" error:

connectionTest("api.ipify.org", 80, "en0");

Is there some way to have the function work in the case of en0? (Preferably without changing the system's routing table just for this one connection?)

Edit:

It looks like the system doesn't know how to route packets through en0 when the VPN is up, unless it has a non-default route for en0.

I tried using the route command to check which route in the table would be used for a specific interface, and I get the following:

$ route get -ifscope en0 1.1.1.1
route: writing to routing socket: not in table

Only -ifscope en0 produces that error. However, the route table indicates there is a default route for en0. Here is the routing table when only ethernet and the VPN are connected (so no Wi-Fi or second VPN):

$ netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
0/1                10.16.0.1          UGSc          165        0  utun10
default            192.168.20.1       UGSc            0        0     en0
10.16/16           10.16.0.8          UGSc            3        0  utun10
10.16.0.8          10.16.0.8          UH              2        0  utun10
127                127.0.0.1          UCS             0        0     lo0
127.0.0.1          127.0.0.1          UH              7  7108160     lo0
128.0/1            10.16.0.1          UGSc           40        0  utun10
169.254            link#8             UCS             1        0     en0      !
192.168.20         link#8             UCS             9        0     en0      !
192.168.20.1/32    link#8             UCS             2        0     en0      !
224.0.0/4          link#22            UmCS            0        0  utun10
224.0.0/4          link#8             UmCSI           1        0     en0      !
224.0.0.251        1:0:5e:0:0:fb      UHmLWI          0        0     en0
255.255.255.255/32 link#22            UCS             0        0  utun10
255.255.255.255/32 link#8             UCSI            0        0     en0      !

There's clearly a default route listed for en0 pointing to its gateway, 192.168.20.1. Why isn't the packet being routed? If I create a static route for 1.1.1.1/32 or even 1/8 it will work. But so long as en0 only has a default route, it won't work. It's like the default route has been disabled somehow.

Edit 2:

If I add a new route to the table using:

$ route add -ifscope en0 0/0 192.168.20.1

so that the routing table now includes the following entry:

Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.20.1       UGScI           1        0     en0

alongside all of the above entries, so there are now two default entries, then the connection works. Why is it necessary for there to be an interface-specific default route in order for this to work?


Solution

Once you added the routing table to your question, your problem became obvious.

It is the routing table that determines to which gateway a packet is sent. The routing table tells the sending host to which gateway the packet is sent. It does that by comparing the destination address to the routes in the routing table. The most-specific (longest match) route is used. A default route is the least-specific (shortest match) route, and it is used as the route of last resort when there are no more-specific routes in the routing table.

Based on the routing table you provided, any packet with a destination address from 1.0.0.0 to 126.255.255.255 (0.0.0.0/8 and 127.0.0.0/8 are exceptions as unusable ranges) will match the 0/1 routing table entry rather than the default route (0/0), and any packet with a destination address from 128.0.0.0 to 223.255.255.255 (224.0.0.0/4 is multicast, and 240.0.0.0/4 is unusable) will match the 128/1 routing table entry rather than the default route (0/0), because the route length of 1 is more specific than the default route length of 0. That means any packets destined to an address in those ranges (combined, all addresses destined for a different network) will be sent to the gateway (10.16.0.1) referenced by the routing table entries for the 0/1 and 128/1 routes.

To solve your problem, you need to remove the 0/1 and 128/1 routing table entries and replace them with one or more entries that are restricted to the networks which the tunnel can reach. With that, the entries not matching the tunnel route(s) or other more specific routing table entries will use the default route.



Answered By - Ron Maupin
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why can my Docker app receive UDP data without publishing the port?

 October 22, 2022     docker, networking, sockets, tcp, udp     No comments   

Issue

I'm learning Docker networking. I'm using Docker Desktop on Windows.

I'm trying to understand the following observations:

Short version in a picture:

enter image description here

Longer version:

First setup (data from container to host)

  • I have a simple app running in a container. It sends one UDP-datagram to a specific port on the host (using "host.docker.internal")

  • I have a corresponding app running on the host. It listens to the port and is supposed to receive the UDP-datagram.

That works without publishing any ports in docker (expected behavior!).

Second setup (data from host to container)

  • I have a simple app on the host. It sends one UDP-datagram to a specific port on the loopback network (using "localhost")

  • I have a corresponding app running in a container. It listens to the port and is supposed to receives the UDP-datagram.

That works only if the container is run with option -p port:port/udp (expected behavior!).

Third setup (combination of the other two)

  • I have an app "Requestor" running in a container. It sends a UDP request-message to a specific port on the host and then wants to receive a response-message.

  • I have a corresponding app "Responder" running on the host. It listens to the port and is supposed to receive the request-message. Then it sends a UDP response-message to the endpoint of the request-message.

This works as well, and - that's what I don't understand - without publishing the port for the response-message!

How does this work? I'm pretty sure there's some basic networking-knowledge that I simply don't have already to explain this. I would be pleased to learn some background on this.

Sidenote:

Since I can do curl www.google.com successfully from inside a container, I realize that a container definitely must not publish ports to receive any data. But there's TCP involved here to establish a connection. UDP on the other hand is "connectionless", so that can't be the (whole) explanation.


Solution

After further investigation, NAT seems to be the answer.

According to these explanations, a NAT is involved between the loopback interface and the docker0 bridge.

This is less recognizable with Docker Desktop for Windows because of the following (source):

Because of the way networking is implemented in Docker Desktop for Windows, you cannot see a docker0 interface on the host. This interface is actually within the virtual machine.



Answered By - 17tmh
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to send tcp packets using raw sockets in winsock?

 October 22, 2022     c++, network-programming, sockets, tcp, winsock     No comments   

Issue

I'm trying to make a client which can send custom packets to a server using raw sockets. I've had success with udp packets but when I try to switch to tcp ones, wireshark doesnt catch anything. I have read that tcp data cannot be shared on raw sockets but I have seen people implementing that in linux. Is the idea of sending tcp packets over raw sockets even correct? And if it is, do I still need to use connect() method in the client code for tcp protocol?

Here's the code I've wrote (works fine with udp packets)

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <iostream>
#include <string>

#pragma comment(lib, "Ws2_32.lib")

#define PORT 9090

using namespace std;

// custom headers

struct tcpheader {
    unsigned short int th_sport;
    unsigned short int th_dport;
    unsigned int th_seq;
    unsigned int th_ack;
    unsigned char th_x2 : 4, th_off : 4;
    unsigned char th_flags;
    unsigned short int th_win;
    unsigned short int th_sum;
    unsigned short int th_urp;
}; /* total tcp header length: 20 bytes (=160 bits) */

struct udphdr
{
    unsigned short udp_sport;
    unsigned short udp_dport;
    unsigned short udp_len;
    unsigned short udp_sum;
};

struct ipheader {
    unsigned char ip_hl : 4, ip_v : 4; /* this means that each member is 4 bits */
    unsigned char ip_tos;
    unsigned short int ip_len;
    unsigned short int ip_id;
    unsigned short int ip_off;
    unsigned char ip_ttl;
    unsigned char ip_p;
    unsigned short int ip_sum;
    unsigned int ip_src;
    unsigned int ip_dst;
}; /* total ip header length: 20 bytes (=160 bits) */

// checksum calculator

uint16_t
checksum(uint16_t* addr, int len)
{
    int count = len;
    register uint32_t sum = 0;
    uint16_t answer = 0;

    while (count > 1) {
        sum += *(addr++);
        count -= 2;
    }

    if (count > 0) {
        sum += *(uint8_t*)addr;
    }

    while (sum >> 16) {
        sum = (sum & 0xffff) + (sum >> 16);
    }

    answer = ~sum;

    return (answer);
}


int main() {

    WSADATA ws;
    char datagram[4096];
    int bOpt = 1;

    // Setting up the enviornment for sockets

    if (WSAStartup(MAKEWORD(2, 2), &ws) != 0) {
        cout << "WSAStartup() failed: " << WSAGetLastError() << endl;
        WSACleanup();
        return -1;
    }

    // Creating a raw socket

    SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

    if (s == INVALID_SOCKET) {
        cout << "WSASocket() failed: " << WSAGetLastError() << endl;
        WSACleanup();
        return -1;
    }

    // definfing the ip and tcp headers

    struct ipheader* iph = (struct ipheader*)datagram;
    // struct udphdr* udph = (struct udphdr*) (datagram + sizeof(struct ipheader));
    struct tcpheader* tcph = (struct tcpheader*)(datagram + sizeof(struct ipheader));
    
    string str = "Hello Server, What's running?";
    char* msg = const_cast<char*> (str.c_str());

    memcpy(datagram + sizeof(struct ipheader) + sizeof(struct udphdr), msg, sizeof(str));
    struct sockaddr_in sendTo;

    sendTo.sin_family = AF_INET;
    sendTo.sin_port = htons(PORT);
    inet_pton(AF_INET, "127.0.0.1", &sendTo.sin_addr);
    
    // memset(datagram, 0, sizeof datagram);

    // filling the packet : setting fields of headers

    // ip header

    iph->ip_hl = 5;
    iph->ip_v = 4;
    iph->ip_tos = 0;
    iph->ip_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
    iph->ip_id = 1;
    iph->ip_off = 0;
    iph->ip_ttl = 255;
    iph->ip_p = 6;
    iph->ip_sum = 0;
    inet_pton(AF_INET, "127.0.0.1", &iph->ip_src);
    iph->ip_dst = sendTo.sin_addr.s_addr;

    // udp header

    // udph->udp_sport = htons(1234);
    // udph->udp_dport = htons(PORT);
    // udph->udp_len = sizeof(struct udphdr);
    // udph->udp_sum = 0;

    // tcp header

    tcph->th_sport = htons(1234);
    tcph->th_dport = htons(PORT);
    tcph->th_seq = rand();
    tcph->th_ack = 0;
    tcph->th_x2 = 0;
    tcph->th_off = 0;
    tcph->th_flags = 2; // SYN 
    tcph->th_win = htons(65535);
    tcph->th_sum = 0;
    tcph->th_urp = 0;

    // calculate checksum

    // udph->udp_sum = checksum((unsigned short*)&udph, sizeof(struct udphdr));
    iph->ip_sum = checksum((unsigned short*)&iph, sizeof(struct ipheader));


    // setting socket option {IP_HDRINCL} for choosing custom ip header instead of kernel header
    
    if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char*)&bOpt, sizeof(bOpt)) == SOCKET_ERROR) {
        cout << "setsockopt(IP_HDRINCL) failed: " << WSAGetLastError() << endl;
        WSACleanup();
        return -1;
    }

    while (1) {
        int val = sendto(s, datagram, sizeof(datagram), 0, (sockaddr*)&sendTo, sizeof(sendTo));
        if (val == -1) {
            cout << "failed to send packet: " << WSAGetLastError() << endl;
            WSACleanup();
            return -1;
        }
        cout << val<<" ";
        Sleep(1000);
    }


    return 0;
} 

I tried various comninations of protocols in socket like IPPROTO_RAW, IPPROTO_TCP, IPPROTO_IP but nothing seems to work with tcp packets


Solution

Windows does not allow TCP packets over RAW sockets, as documented on MSDN:

https://learn.microsoft.com/en-us/windows/win32/winsock/tcp-ip-raw-sockets-2

On Windows 7, Windows Vista, Windows XP with Service Pack 2 (SP2), and Windows XP with Service Pack 3 (SP3), the ability to send traffic over raw sockets has been restricted in several ways:

  • TCP data cannot be sent over raw sockets.

  • ...

Linux does not have the same restriction that Windows does.



Answered By - Remy Lebeau
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What is a message boundary?

 October 22, 2022     networking, sockets, tcp, udp     No comments   

Issue

What is "message bonudaries" in the following context?

One difference between TCP and UDP is that UDP preserves message boundaries.

I understand the difference between TCP and UDP, but unsure about the definition of "message boundaries". Since UDP includes the destination and port information in each individual packet, could it be this that gives message a "boundary"?


Solution

No, message boundaries have nothing to do with destinations or ports. A "message boundary" is the separation between two messages being sent over a protocol. UDP preserves message boundaries. If you send "FOO" and then "BAR" over UDP, the other end will receive two datagrams, one containing "FOO" and the other containing "BAR".

If you send "FOO" and then "BAR" over TCP, no message boundary is preserved. The other end might get "FOO" and then "BAR". Or it might get "FOOBAR". Or it might get "F" and then "OOB" and then "AR". TCP does not make any attempt to preserve application message boundaries -- it's just a stream of bytes in each direction.



Answered By - David Schwartz
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why does only Firefox display the response from this HTTP server?

 October 22, 2022     c++, http, http-headers, sockets, tcp     No comments   

Issue

I'm trying to get straight in my head the relationship between HTTP and TCP.

I tried to resolve (what I perceived as) contradictory answers from a web search of "tcp vs http" by writing a server that listens at a TCP socket bound to some address+port, then typing that address+port into a web brower.

Having done so, I saw that the content received at the accept()ed socket was text with human-readable "HTTP stuff" (my knowledge of HTTP isn't enough to intelligently identify the content).

From Chrome, my server receives:

GET / HTTP/1.1
Host: 127.0.0.23:9018
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

...and from Firefox, my server receives:

GET / HTTP/1.1
Host: 127.0.0.23:9018
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

From the above results, I conjectured that HTTP is sending HTTP-conformant bytes (is it always ASCII?) over a TCP connection to a server's socket that has been accept()ed after listen()ing to a specific address+port.

So I further conjectured that in order to get content to show up in a web browser that connects to the address+port that my server is listen()ing at, my server should write() some kind of HTTP-compliant response to the socket.

This Stack Overflow Q&A gave me a candidate minimal HTTP response.

Putting it all together, my server's MCVE code is:

#include <arpa/inet.h>                                                                         
#include <cerrno>                                                                              
#include <cstdio>                                                                              
#include <cstring>                                                                             
#include <fcntl.h>                                                                             
#include <iostream>                                                                            
#include <netinet/in.h>                                                                        
#include <pthread.h>                                                                           
#include <semaphore.h>                                                                         
#include <stdexcept>                                                                           
#include <sstream>                                                                             
#include <sys/types.h>                                                                         
#include <sys/socket.h>                                                                        
#include <unistd.h>                                                                            
                                                                                               
#define IP "127.0.0.23"                                                                        
#define PORT (9018)                                                                            
                                                                                               
/**                                                                                            
 * A primitive, POC-level HTTP server that accepts its first incoming connection               
 * and sends back a minimal HTTP OK response.                                                  
 */                                                                                            
class Server {                                                                                 
private:                                                                                       
  static const std::string ip_;                                                                
  static const std::uint16_t port_{PORT};                                                      
  int listen_sock_;                                                                            
  pthread_t tid_;                                                                              
                                                                                               
public:                                                                                        
  /**                                                                                          
   * Ctor: create and bind listen_sock_ and start a thread for startRoutine().                 
   */                                                                                          
  Server() {                                                                                   
    using namespace std;                                                                       
    int result;                                                                                
                                                                                               
    if (! createSocket()) { throw runtime_error("failed creating socket"); }                   
    if (! bindSocket()) { throw runtime_error("failed binding socket"); }                      
                                                                                               
    if ((result = pthread_create(&tid_, NULL, startRoutine, this))) {                          
      std::stringstream ss;                                                                    
                                                                                               
      ss << "pthread_create() error " << errno << "(" << result << ")";                        
      std::cerr << ss.str() << std::endl;                                                      
      throw runtime_error("failed spawning Server thread");                                    
    }                                                                                          
  }                                                                                            
                                                                                               
  /** Dtor: wait for the spawned thread and destroy listen_sock_. */                           
  ~Server() {                                                                                  
    pthread_join( tid_, NULL );                                                                
    destroySocket();                                                                           
  }                                                                                            
                                                                                               
private:                                                                                       
  /** Creates listen_sock_ as a stream socket. */                                              
  bool createSocket() {                                                                        
    listen_sock_ = socket(PF_INET, SOCK_STREAM, 0);                                            
                                                                                               
    if (listen_sock_ < 0) {                                                                    
      std::stringstream ss;                                                                    
                                                                                               
      ss << "socket() error " << errno << "(" << strerror(errno) << ")";                       
      std::cerr << ss.str() << std::endl;                                                      
    }                                                                                          
                                                                                               
    return (listen_sock_ >= 0);                                                                
  }                                                                                            
                                                                                                                                                                                                                                                                                                                                                                                    [138/573]
  /** Shuts down and closes listen_sock_. */                                                   
  void destroySocket() {                                                                       
    if (listen_sock_ >= 0) {                                                                   
      shutdown(listen_sock_, SHUT_RDWR);                                                       
      close(listen_sock_);                                                                     
    }                                                                                          
  }                                                                                            

  /** Binds listen_sock_ to ip_ and port_. */                                                  
  bool bindSocket() {                                                                          
    int ret;                                                                                   
    sockaddr_in me;                                                                            
    me.sin_family = PF_INET;                                                                   
    me.sin_port = htons(port_);                                                                
    me.sin_addr.s_addr = inet_addr(ip_.c_str());
    int optval = 1;                                                                            

    setsockopt(listen_sock_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);

    if ((ret = bind(listen_sock_, (sockaddr*)&me, sizeof me))) {
      std::stringstream ss;                                                                    

      ss << "bind() error " << errno << "(" << strerror(errno) << ")";
      std::cerr << ss.str() << std::endl;                                                      
    }                                                                                          

    return (! ret);                                                                            
  }                                                                                            

  /**                                                                                          
   * Accept a connection from listen_sock_.                                                    
   * Caller guarantees listen_sock_ has been listen()ed to already.
   * @param tv [in, out] How long to wait to accept a connection.
   * @return accepted socket; -1 on any error.                                                 
   */                                                                                          
  int acceptConnection(timeval& tv) {                                                          
    int sock = -1;                                                                             
    int ret;                                                                                   
    fd_set readfds;                                                                            
    sockaddr_in peer;                                                                          
    socklen_t addrlen = sizeof peer;                                                           

    FD_ZERO(&readfds);                                                                         
    FD_SET(listen_sock_, &readfds);                                                            
    ret = select(listen_sock_ + 1, &readfds, NULL, NULL, &tv);

    if (ret < 0) {                                                                             
      std::stringstream ss;                                                                    

      ss << "select() error " << errno << "(" << strerror(errno) << ")";
      std::cerr << ss.str() << std::endl;                                                      

      return sock;                                                                             
    }                                                                                          
    else if (! ret) {                                                                          
      std::cout << "no connections within " << tv.tv_sec << "seconds"
        << std::endl;                                                                          

      return sock;                                                                             
    }                                                                                          

    if ((sock = accept(listen_sock_, (sockaddr*)&peer, &addrlen)) < 0) {
      std::stringstream ss;                                                                    

      ss << "accept() error " << errno << "(" << strerror(errno) << ")";
      std::cerr << ss.str() << std::endl;                                                      
    }                                                                                          
    else {                                                                                     
      std::stringstream ss;                                                                    

      ss << "socket " << sock << " accepted connection from "
        << inet_ntoa( peer.sin_addr ) << ":" << ntohs(peer.sin_port);
      std::cout << ss.str() << std::endl;                                                      
    }                                                                                          

    return sock;                                                                               
  }
                                                                                                                                                                                                                                                                                                                                                                                     [60/573]
  /** Read from the specified socket and dump to stdout. */
  static void dumpReceivedContent(const int& sock) {
    fd_set readfds;                                                                            
    struct timeval tv = {30, 0};                                                               
    int ret;                                                                                   

    FD_ZERO(&readfds);                                                                         
    FD_SET(sock, &readfds);                                                                    
    ret = select(sock + 1, &readfds, NULL, NULL, &tv);

    if (ret < 0) {                                                                             
      std::stringstream ss;                                                                    

      ss << "select() error " << errno << "(" << strerror(errno) << ")";
      std::cerr << ss.str() << std::endl;                                                      

      return;                                                                                  
    }                                                                                          
    else if (! ret) {                                                                          
      std::cout << "no content received within " << tv.tv_sec << "seconds"
        << std::endl;                                                                          

      return;                                                                                  
    }                                                                                          

    if (FD_ISSET(sock, &readfds)) {                                                            
      ssize_t bytes_read;                                                                      
      char buf[80] = {0};                                                                      

      fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
      std::cout << "received content:" << std::endl;
      std::cout << "----" << std::endl;                                                        
      while ((bytes_read = read(sock, buf, (sizeof buf) - 1)) >= 0) {
        buf[bytes_read] = '\0';                                                                
        std::cout << buf;                                                                      
      }                                                                                        
      std::cout << std::endl << "----" << std::endl;
    }                                                                                          
  }                                                                                            

  /** Write a minimal HTTP OK response to the specified socker. */
  static void sendMinHttpResponse(const int& sock) {
    static const std::string resp =                                                            
      "HTTP/1.1 200 OK\r\n"                                                                    
      "Content-Length: 13\r\n"                                                                 
      "Content-Type: text/plain\r\n\r\nHello World!";
    write(sock, resp.c_str(), resp.length());                                                  
  }                                                                                            

  /**                                                                                          
   * Thread start routine: listen for, then accept connections; dump received
   * content; send a minimal response.                                                         
   */                                                                                          
  static void* startRoutine(void* arg) {                                                       
    Server* s;                                                                                 

    if (! (s = (Server*)arg)) {                                                                
      std::cout << "Bad arg" << std::endl;                                                     
      return NULL;                                                                             
    }                                                                                          

    if (listen(s->listen_sock_, 3)) {                                                          
      std::stringstream ss;                                                                    

      ss << "listen() error " << errno << "(" << strerror(errno) << ")";
      std::cerr << ss.str() << std::endl;                                                      

      return NULL;                                                                             
    }                                                                                          

    std::cout << "Server accepting connections at "
      << s->ip_ << ":" << s->port_ << std::endl;

    {                                                                                          
      timeval tv = { 30, 0 };                                                                  

      int sock = s->acceptConnection(tv);                                                      

      if (sock < 0) {                                                                          
        std::cout << "no connections accepted" << std::endl;

        return NULL;                                                                           
      }                                                                                        

      dumpReceivedContent(sock);                                                               
      sendMinHttpResponse(sock);                                                               
      shutdown(sock, SHUT_RDWR);                                                               
      close(sock);                                                                             
    }                                                                                          

    return NULL;                                                                               
  }                                                                                            
};                                                                                             

const std::string Server::ip_{IP};                                                             

int main( int argc, char* argv[] ) {                                                           
  Server s;                                                                                    
  return 0;                                                                                    
}

When I point Chrome and Chromium browsers to my server (127.0.0.23:9018), I get a blank page with no content, but when I point Firefox to my server, I get the "Hello world!" string that I wanted.

Why does this only work with Firefox, and not with Chrome or Chromium?


Solution

Your server responds with an invalid data size Content-Length: 13.

  1. The data is Hello World!, the size is 12.
  2. resp.length() does not count \0, thus the server does not send Hello World!\0.

The header must be Content-Length: 12.



Answered By - 273K
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What is the difference between epoll and multiple connect attempt?

 October 22, 2022     c++, io, networking, sockets, tcp     No comments   

Issue

Let's say i have a non blocking TCP client socket. I want to connect to a TCP server. I found that either of the following ways can be used to do so.

int num_of_retry=5;
for(int i=0;i<num_of_retry;i++){
   connect(SOCKET_FD,...);
   sleep(1000ms);
}

and this

connect(SOCKET_FD,...);
epoll_wait(...,5000ms)

What are the main difference in the above two approaches, performance and otherwise?


Solution

In this particular example, the main difference is that sleep() will not exit until the full interval has elapsed, whereas epoll() (and select(), too) will exit sooner if the pending connect operation finishes before the full interval has elapsed.

Otherwise, both examples are blocking the calling thread until something happens (which kind of defeats the purpose of using a non-blocking socket - except that this approach is the only way to implement a timeout with connect()).

Note that in either example, if you call connect() on a socket while it is already working on connecting, connect() will fail with an EALREADY error. If a connect operation times out, you should close() the socket and create a new socket before calling connect() again. And you should wait for epoll() (or select()) to tell you when the operation is finished, don't just call connect() in a loop until it reports something other than EALREADY.



Answered By - Remy Lebeau
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] When read() rates is slower than arrived TCP packet rate

 October 22, 2022     sockets, system-calls, tcp     No comments   

Issue

My question

At receiver side, when the system call read() is slower than the TCP packets arrived rate, Does the packet loss and re-transmission occur? If it does, could you give me a little hint why this retransmission happen?

What I did for finding answers.

(1) I generated lots of TCP packets from a sender host.

(2) A receiver host read packet from its socket buffer. Its buffer is small (1kbyte)

(3) I found [PSH-ACK TCP packet] re-transmission occur at the receiver host.

My guess

(1) I decided that slow read() can make re-transmission.

(2) I know the receive socket buffer overflow when it receive more packets than its size. But this is different from the above.


Solution

TCP protocol itself have several different mechanisms for handling bottlenecks. For example (google details):

  • Slow start
  • Flow control
  • Congestion control

Shortly: TCP stack uses windows for avoid sending more data to the peer than it can store to receiving queue.

When a sender try to send faster than network/receiver can handle, the output queue of TCP stack of the sender will fill up. When the queue is full, then the sender notices this by few ways:

  • with blocking socket: send() call will block.
  • with unblocking socket: send() call will fail with errno EAGAIN or EWOULDBLOCK.
  • whith select() call: writefd-set won't indicate writing possibility.

This way the TCP stack can automatically slow down the sender, and so minimize packet lost in network/receiving end.

EDIT:

Tcpdump example, where server (B) does not call recv() after accept():

~ # tcpdump -i eth0 "tcp port 12345"
21:44:16.255183  A > B:  seq 2052761822, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
21:44:16.255484  B > A:  seq 2110966471, ack 2052761823, win 7300, options [mss 1460,nop,nop,sackOK], length 0
21:44:16.256065  A > B:  ack 1, win 64240, length 0
21:44:20.338089  A > B:  seq 1:1461, ack 1, win 64240, length 1460
21:44:20.338365  B > A:  ack 1461, win 5840, length 0
21:44:20.338754  A > B:  seq 1461:2921, ack 1, win 64240, length 1460
21:44:20.338978  B > A:  ack 2921, win 5840, length 0
21:44:20.339357  A > B:  seq 2921:4381, ack 1, win 64240, length 1460
21:44:20.339759  A > B:  seq 4381:5841, ack 1, win 64240, length 1460
21:44:20.340175  A > B:  seq 5841:7301, ack 1, win 64240, length 1460
21:44:20.340571  A > B:  seq 7301:8761, ack 1, win 64240, length 1460
21:44:20.373395  B > A:  ack 8761, win 1460, length 0
21:44:20.374367  A > B:  seq 8761:10221, ack 1, win 64240, length 1460
21:44:20.413398  B > A:  ack 10221, win 0, length 0
21:44:20.714460  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:20.714725  B > A:  ack 10221, win 0, length 0
21:44:21.314796  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:21.315055  B > A:  ack 10221, win 0, length 0
21:44:22.515652  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:22.515925  B > A:  ack 10221, win 0, length 0
21:44:24.917211  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:24.917473  B > A:  ack 10221, win 0, length 0
21:44:29.718352  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:29.718612  B > A:  ack 10221, win 0, length 0
21:44:39.331520  A > B:  seq 10221:10222, ack 1, win 64240, length 1
21:44:39.331789  B > A:  ack 10221, win 0, length 0

The client (A) tries to send big segments to server (B) until the server starts advertise window size 0. After this point the client (A) start using segment size 1 byte, and period between re-transmission start increasing. It looks like, that TCP stack tries to minimize traffic that is needed for polling the window.

RFC-793 says the following (Later RFCs may specify this better):

The sending TCP must be prepared to accept from the user and send at least one octet of new data even if the send window is zero. The
sending TCP must regularly retransmit to the receiving TCP even when
the window is zero. Two minutes is recommended for the retransmission interval when the window is zero. This retransmission is essential to guarantee that when either TCP has a zero window the re-opening of the window will be reliably reported to the other.

When the receiving TCP has a zero window and a segment arrives it must still send an acknowledgment showing its next expected sequence number and current window (zero).



Answered By - SKi
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to properly destroy a socket so that it is ready to be called again after program exits? (Node.js)

 October 22, 2022     node.js, sockets, tcp     No comments   

Issue

He is a bit of code where a server is created to listen on port 2222:

import { createServer } from 'net';

const server = createServer((c) => {
  c.setEncoding('utf8');
  c.on('data', (data) => {
    console.log('server', data);
    c.write(data);
  });
  c.on('error', (e) => { throw e; });
});
server.listen(2222);

and the code to create a connection to the server to send a simple 'hello' that the server will respond back to. After 2 seconds, the socket gets destroyed.

import { createConnection } from 'net';

const socket = createConnection({ localPort: 9999, port: 2222, host: 'localhost' });
socket.setEncoding('utf8');
socket.on('data', (data) => {
  console.log('socket data', data);
});
socket.on('connect', () => {
  socket.write('hello');
});
socket.setTimeout(2000);
socket.on('timeout', () => { socket.destroy(); console.log('destroyed'); });
socket.on('error', (e) => { throw e; });

This code works well the first time it is called.

It will fail on subsequent calls with:

Error: connect EADDRINUSE 127.0.0.1:2222 - Local (0.0.0.0:9999)
  errno: -48,
  code: 'EADDRINUSE',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 2222

It took me a while to figure it out, but the problem comes from trying to bind the socket on an outbound port: localPort: 9999. Without specifying this parameter, the OS will select a free port, and the program won't crash.

When specifying it, a cooldown of ~15s is required before the socket being re-usable again.

  • Is there a way to properly destroy the socket so that it becomes immediately available again?
  • If not, is there a way to verify that the socket is "cooling down", but will eventually be available again? I'd like to distinguish the case where I just have to wait from the one where the socket has been actively taken by another process, and won't be released to the pool of free sockets.

Any theory on why the socket is not available after the program exists is welcome!


Solution

The socket is going into a CLOSE_WAIT state, so you have to wait until it is available again before you can reconnect. You can try to avoid this by:

Removing the source socket and letting the platform pick a random ephemeral one for you (as you have already found out).

Closing the connection at the server end first (so the CLOSE_WAIT ends up there). See server.close();

Resetting the client connection. See socket.resetAndDestroy()



Answered By - Buffoonism
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] what happen when you run client without server running?

 October 22, 2022     c, sockets, tcp, tcpclient, wireshark     No comments   

Issue

I got an interview question in sockets in c programming I got two files server.c and client.c

I was asked what will happen if you run a client when the server is not running : more specifically

run ./client localhost without running ./server in a different terminal

and I didn't know the answer (obviously it won't connect but what will happen I don't know) they wanted an answer that was related to the sockets

when I checked in Wireshark to see if I can get some information I saw this: the focus on the red record of the TCP sockets

the focus on the red record of the TCP sockets and the one record above it.

9999 is the port of the server what is the meaning of every parameter here?

56020 ->9999 [SYN] Seq=0 Win=65495 Len=0 MSS=65495 SACK_PERM=1 TSval=736093598 TSecr=0 WS=128

and also what is the meaning of

9999 -> 56020 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0

I tried to look for the meaning in google but didn't find results that related to sockets. thank you very much in advanced!

code for the client.c

// to run in the terminal compile with 
// gcc -o client client.c -Wall  
// then run the following command:
// ./client localhost

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SIM_LENGTH 10
// #define IP_ADDRESS "127.0.0.1" // from the last part we put this in comment and resolve it with gethostbyname
#define PORT 9999

int main(int argc, char *argv[])
{
  int sock;
  struct sockaddr_in cli_name;
  int count;
  int value;
  char *hostname;
  char *hostaddr;
  struct addrinfo *res;
  struct sockaddr_in *saddr;
  printf("Client is alive and establishing socket connection.\n");
  printf("%d  %s\n", argc, argv[1]);
  if (argc != 2)
  {
    perror("Usage: hostnamelookup <hostname> error \n");
    exit(1);
  }

  hostname = argv[1]; // hostname is the first argument
  printf("Hostname is %s\n", hostname);

  if (0 != getaddrinfo(hostname, NULL, NULL, &res)) // getaddrinfo is a function that returns a struct addrinfo* that
  // contains a linked list of struct addrinfo (from nslookup.c)
  {
    fprintf(stderr, "Error in resolving hostname %s\n", hostname);
    exit(1);
  }

  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0)
  {
    perror("Error opening channel");
    close(sock);
    exit(1);
  }

  saddr = (struct sockaddr_in *)res->ai_addr; // get the address of the server socket address structure (from nslookup.c)
  hostaddr = inet_ntoa(saddr->sin_addr);      // get the IP address of the server (from nslookup.c)

  bzero(&cli_name, sizeof(cli_name));
  cli_name.sin_family = AF_INET;
  cli_name.sin_addr.s_addr = inet_addr(hostaddr); // set the IP address of the client (from nslookup.c)
  cli_name.sin_port = htons(PORT);

  if (connect(sock, (struct sockaddr *)&cli_name, sizeof(cli_name)) < 0)
  {
    perror("Error establishing communications");
    close(sock);
    exit(1);
  }

  for (count = 1; count <= SIM_LENGTH; count++)
  {
    read(sock, &value, 4);
    printf("Client has received %d from socket.\n", value);
  }

  printf("Exiting now.\n");

  close(sock);
  exit(0);
}

server.c

// to run in the terminal compile with 
// gcc -o server server.c -Wall  
// then run the following command:
// ./server 
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SIM_LENGTH 10
#define PORT 9999

int main(void)
{
  int sock;                     // socket descriptor
  int connect_sock;             // socket descriptor for the connection
  struct sockaddr_in serv_name; // server socket address structure
  socklen_t len;                // length of the socket address structure
  int count;                    // number of bytes received

  sock = socket(AF_INET, SOCK_STREAM, 0); // create a socket
                                          // check if the socket is valid
  if (sock < 0)
  {
    perror("Error opening channel");
    exit(1);
  }
  // initialize the server socket address structure
  bzero(&serv_name, sizeof(serv_name)); // clear the structure
  serv_name.sin_family = AF_INET;       // set the family to Internet
  serv_name.sin_port = htons(PORT);     // set the port number

  // check if the bind is successful
  if (bind(sock, (struct sockaddr *)&serv_name, sizeof(serv_name)) < 0) // bind the socket to the server address
  {
    perror("Error on binding");
    exit(1);
  }

  // listen for connections
  if (listen(sock, 1) < 0) // listen for connections on the socket
  {
    perror("Error on listening");
    exit(1);
  }

  len = sizeof(serv_name); // get the length of the socket address structure

  connect_sock = accept(sock, (struct sockaddr *)&serv_name, &len); // accept a connection on the socket
                                                                    // check if the connection is valid
  if (connect_sock < 0)
  {
    perror("Error on accepting");
    exit(1);
  }
  for (count = 1; count <= SIM_LENGTH; count++) // loop to send the data
  {
    write(connect_sock, &count, 4);                      // send the data
    printf("Server has written %d to socket.\n", count); // print the data
  }

  close(connect_sock); // close the connection
  close(sock);         // close the socket
}

Solution

If the host on that IP is completely down and unreachable (or the destination port is effectively firewalled), then the client will retry initiating the three way handshake a few times before timing out and bubbling up an error to the socket application calling connect.

If the host is up, but not listening on the expected port, it will send back an RST in response to receiving SYN from the client. That will effectively tell the client to "go away, I'm not listening". And the TCP stack will again bubble up an error to the socket application to trigger its connect call to return an error.



Answered By - selbie
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to route TCP traffic through Tor proxy?

 October 22, 2022     netcat, python-3.x, sockets, tcp, tor     No comments   

Issue

I would like to create a TCP connection using python library socket. This traffic should be redirected through Tor network but socks.SOCKS5Error: 0x01: General SOCKS server failure is given.

The code below can connect to Tor proxy and gives a new Tor IP.

from stem.control import Controller
from stem import Signal
import socket
import socks

if __name__ == "__main__":
        with Controller.from_port(port=9051) as controller:
            # Creatting TOR connection
            controller.authenticate(password='password')
            controller.signal(Signal.NEWNYM)
    
            socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "192.168.1.148", 9050)
            socket.socket = socks.socksocket
            
            # Creatting socket connection
            new_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            host = '192.168.1.148'
            port = 50007
    
            new_socket.connect((host, port))
            new_socket.sendall('Hello world')
            print(new_socket.recv(1024))

This is the error given:

Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/socks.py", line 809, in connect
    negotiate(self, dest_addr, dest_port)
  File "/usr/lib/python3.10/site-packages/socks.py", line 443, in _negotiate_SOCKS5
    self.proxy_peername, self.proxy_sockname = self._SOCKS5_request(
  File "/usr/lib/python3.10/site-packages/socks.py", line 533, in _SOCKS5_request
    raise SOCKS5Error("{:#04x}: {}".format(status, error))
socks.SOCKS5Error: 0x01: General SOCKS server failure

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/keylogger-project/./tor_proxy_connection.py", line 74, in <module>
    tor.__testing_socket_availability__()
  File "/home/pi/keylogger-project/./tor_proxy_connection.py", line 66, in __testing_socket_availability__
    self.socket.connect((host, port))
  File "/usr/lib/python3.10/site-packages/socks.py", line 47, in wrapper
    return function(*args, **kwargs)
  File "/usr/lib/python3.10/site-packages/socks.py", line 814, in connect
    raise GeneralProxyError("Socket error", error)
socks.GeneralProxyError: Socket error: 0x01: General SOCKS server failure

Server side is a simple nc -lvp 50007

Regards


Solution

        socket.socket = socks.socksocket
        ...
        host = '192.168.1.148'
        ...
        new_socket.connect((host, port))

The target 192.168.1.148 is an IP address reserved for private networks and thus not reachable from the internet. But the nodes on the Tor network are on the internet and thus cannot reach the given target.



Answered By - Steffen Ullrich
Answer Checked By - David Marino (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] When should I use TCP_NODELAY and when TCP_CORK?

 October 22, 2022     linux, sockets, tcp     No comments   

Issue

I understood that both of them disable Nagle's algorithm.

When should/ shouldn't I use each one of them?


Solution

First of all not both of them disables Nagle's algorithm.

Nagle's algorithm is for reducing more number of small network packets in wire. The algorithm is: if data is smaller than a limit (usually MSS), wait until receiving ACK for previously sent packets and in the mean time accumulate data from user. Then send the accumulated data.

if [ data > MSS ]
    send(data)
else
    wait until ACK for previously sent data and accumulate data in send buffer (data)
    And after receiving the ACK send(data)

This will help in applications like telnet. However, waiting for the ACK may increase latency when sending streaming data. Additionally, if the receiver implements the 'delayed ACK policy', it will cause a temporary deadlock situation. In such cases, disabling Nagle's algorithm is a better option.

So TCP_NODELAY is used for disabling Nagle's algorithm.

TCP_CORK aggressively accumulates data. If TCP_CORK is enabled in a socket, it will not send data until the buffer fills to a fixed limit. Similar to Nagle's algorithm, it also accumulates data from user but until the buffer fills to a fixed limit not until receiving ACK. This will be useful while sending multiple blocks of data. But you have to be more careful while using TCP_CORK.

Until 2.6 kernel, both of these options are mutually exclusive. But in later kernel, both of them can exist together. In such case, TCP_CORK will be given more preference.

Ref:

  • http://baus.net/on-tcp_cork/
  • http://ccr.sigcomm.org/archive/2001/jan01/ccr-200101-mogul.pdf


Answered By - theB
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] how to do something like streams inside a port (Python socket)

 October 22, 2022     multithreading, port, python, sockets, tcp     No comments   

Issue

there is such a code:

server:

import socket
from threading import Thread
from time import sleep

sock = socket.socket()

sock.bind(('', 1337))
sock.listen(1)
conn, addr = sock.accept()
def func1():
    while True:
        conn.send("1".encode("utf-8"))
        sleep(0.5)
def func2():
    while True:
        conn.send("2".encode("utf-8"))
        sleep(0.5)
t1 = Thread(target=func1)
t1.start()
t2 = Thread(target=func2)
t2.start()

client:

import socket
from threading import Thread
from time import sleep

sock = socket.socket()
sock.connect(('localhost', 1337))

def func1():
    while True:
        data = sock.recv(1024).decode("utf-8")
        if data != "1":
            print("the package did not arrive properly")
        else:
            print("package arrived ok")
def func2():
    while True:
        data = sock.recv(1024).decode("utf-8")
        if data != "2":
            print("the package did not arrive properly")
        else:
            print("package arrived ok")
t1 = Thread(target=func1)
t1.start()
t2 = Thread(target=func2)
t2.start()

I need to make sure that the packet sent by function1 comes to function1, and the packet of function2 comes to function2, but this code does not work correctly, and packets from function1 often end up in function2 and vice versa


Solution

I feel like you are approaching this from the wrong direction. You do not need multiple threads in the server or client. If you have multiple threads that is fine, but that's really not relevant for the problem you are having.

You are trying to multiplex multiple different types of messages over a single socket connections. In other words, you need a communication protocol.

On top of that, you have another problem that you do not appear to be aware of yet. Sockets are streams of bytes, in particular, they are not messages. If you send multiple messages in quick succession, they might be truncated or combined in the receiver.

If you send the following packages:

1
2
1
1
2

They could be received as follows:

12
112

Then your receiver will be very confused. Again, this problem can be resolved with a communication protocol.


There are many different ways to implement a communication protocol. The simplest that I can think of is to use JSON:

# sender.py

import socket
import time
import json

sock = socket.socket()

# https://stackoverflow.com/a/6380198/8746648
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

sock.bind(('', 1337))
sock.listen(1)
conn, addr = sock.accept()

while True:
    # If necessary, you can make these calls from different threads.
    # Notice, that we append a newline at the end, this is needed for 'readline' to work properly.
    conn.send(json.dumps({ "type": 1, "payload": 42 }).encode("utf-8") + b"\n")
    time.sleep(0.5)
    conn.send(json.dumps({ "type": 2, "payload": "can-be-anything" }).encode("utf-8") + b"\n")
    time.sleep(0.5)
# receiver.py

import socket
import json

sock = socket.socket()
sock.connect(('localhost', 1337))

# We know, that the messages themselves do not contain newline characters
# and the server sends a newline after each message, therefore, this will receive a complete message.
sock_file = sock.makefile()
while line := sock_file.readline():
    object_ = json.loads(line)

    # If you want to you can handle the messages in different threads.
    # This could be done by setting up a queue that is consumed by working threads.
    if object_["type"] == 1:
        print(f"received(1): {object}")
    elif object_["type"] == 2:
        print(f"received(2): {object}")


Answered By - asynts
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How do I debug error ECONNRESET in Node.js?

 October 22, 2022     express, node.js, sockets, tcp     No comments   

Issue

I'm running an Express.js application using Socket.io for a chat webapp and I get the following error randomly around 5 times during 24h. The node process is wrapped in forever and it restarts itself immediately.

The problem is that restarting Express kicks my users out of their rooms and nobody wants that.

The web server is proxied by HAProxy. There are no socket stability issues, just using websockets and flashsockets transports. I cannot reproduce this on purpose.

This is the error with Node v0.10.11:

    events.js:72
            throw er; // Unhandled 'error' event
                  ^
    Error: read ECONNRESET     //alternatively it s a 'write'
        at errnoException (net.js:900:11)
        at TCP.onread (net.js:555:19)
    error: Forever detected script exited with code: 8
    error: Forever restarting script for 2 time

EDIT (2013-07-22)

Added both socket.io client error handler and the uncaught exception handler. Seems that this one catches the error:

    process.on('uncaughtException', function (err) {
      console.error(err.stack);
      console.log("Node NOT Exiting...");
    });

So I suspect it's not a Socket.io issue but an HTTP request to another server that I do or a MySQL/Redis connection. The problem is that the error stack doesn't help me identify my code issue. Here is the log output:

    Error: read ECONNRESET
        at errnoException (net.js:900:11)
        at TCP.onread (net.js:555:19)

How do I know what causes this? How do I get more out of the error?

Ok, not very verbose but here's the stacktrace with Longjohn:

    Exception caught: Error ECONNRESET
    { [Error: read ECONNRESET]
      code: 'ECONNRESET',
      errno: 'ECONNRESET',
      syscall: 'read',
      __cached_trace__:
       [ { receiver: [Object],
           fun: [Function: errnoException],
           pos: 22930 },
         { receiver: [Object], fun: [Function: onread], pos: 14545 },
         {},
         { receiver: [Object],
           fun: [Function: fireErrorCallbacks],
           pos: 11672 },
         { receiver: [Object], fun: [Function], pos: 12329 },
         { receiver: [Object], fun: [Function: onread], pos: 14536 } ],
      __previous__:
       { [Error]
         id: 1061835,
         location: 'fireErrorCallbacks (net.js:439)',
         __location__: 'process.nextTick',
         __previous__: null,
         __trace_count__: 1,
         __cached_trace__: [ [Object], [Object], [Object] ] } }

Here I serve the flash socket policy file:

    net = require("net")
    net.createServer( (socket) =>
      socket.write("<?xml version=\"1.0\"?>\n")
      socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
      socket.write("<cross-domain-policy>\n")
      socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
      socket.write("</cross-domain-policy>\n")
      socket.end()
    ).listen(843)

Can this be the cause?


Solution

A simple tcp server I had for serving the flash policy file was causing this. I can now catch the error using a handler:

# serving the flash policy file
net = require("net")

net.createServer((socket) =>
  //just added
  socket.on("error", (err) =>
    console.log("Caught flash policy server socket error: ")
    console.log(err.stack)
  )

  socket.write("<?xml version=\"1.0\"?>\n")
  socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
  socket.write("<cross-domain-policy>\n")
  socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
  socket.write("</cross-domain-policy>\n")
  socket.end()
).listen(843)


Answered By - Samson
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why is this port still open after I killed the process which occupied this port?

 October 22, 2022     cmd, networking, port, sockets, tcp     No comments   

Issue

I typed this command in Windows cmd:

netstat -nao | findstr 9300

The output is:

  TCP    0.0.0.0:9300           0.0.0.0:0              LISTENING       6676
  TCP    10.206.90.163:59300    180.181.184.37:443     ESTABLISHED     1960
  TCP    127.0.0.1:9300         127.0.0.1:5907         ESTABLISHED     6676
  TCP    127.0.0.1:9300         127.0.0.1:5908         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5908         ESTABLISHED     6676
  TCP    127.0.0.1:9300         127.0.0.1:5909         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5913         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5914         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5914         ESTABLISHED     6676
  TCP    127.0.0.1:9300         127.0.0.1:5914         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5915         ESTABLISHED     6676
  TCP    127.0.0.1:9300         127.0.0.1:5917         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5917         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5917         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5917         TIME_WAIT       0
  TCP    127.0.0.1:9300         127.0.0.1:5918         TIME_WAIT       0

Then I found that port 9300 was occupied by the process whose PID is 6676. Then I checked the process's name by typing, and killed this process:

tasklist | findstr 6676

After I killed this, I typed the following command to check which port is still open.

netstat -a

The output is:

TCP    0.0.0.0:9300           DESKTOP-7AI5AKV:0      LISTENING

How could this be possible? I just closed this port. How could this still be listening?


Solution

A service in listening mode on all ports will show in netstat as this:

0.0.0.0:9300

You can locate which process is listening to this port with this command:

% lsof | grep LISTEN
sshd        511                           root    3u     IPv4              12453      0t0        TCP *:ssh (LISTEN)

For example, my sshd is currently pid = 511.

Killing the server PID will have the server restarted by the init system (e.g. systemd on Linux or launch services on macOS). You can encourage the server to restart by doing kill -15 511 for PID 511. You can also try -9 if it does not restart.

The ESTABLISHED and TIME_WAIT are active connections and closed pending 2 minute expire timer clearing.



Answered By - James Risner
Answer Checked By - Timothy Miller (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I detect what program is listening to a TCP/IP port in Windows?

 October 22, 2022     ip, port, sockets, tcp, vb6     No comments   

Issue

I have an application that I inherited that listens on port 7001 for UDP broadcasts from our in-house test equipment, and I recently updated another application that needs to do the same thing. Both applications must be able to coexist on the same computer.

Currently, when my recently updated application attempts to bind to the port to listen for UDP broadcasts and fails, it simply reports that the port is not available and suggests that the inherited application is probably running. How can I get my application to detect what application is actually listening on that port? I've done a Google search and have even searched this site, but so far I have been unable to find anything except to use Task Manager, TCPView, or netstat at the command line.

I would prefer a technique that either uses the Windows API or a Windows system COM component, since both applications are written in Visual Basic 6.0. (I know, I know, but I must maintain these applications since they are mission critical.) However, a .NET solution would would also be useful in case I need it in my new development efforts.


Solution

Use:

netstat -n -o

That will show the process ID and from there you can either look in the Task Manager's process viewer, go to menu View → Columns... and check the Process ID (PID). Then you can see the name of the process listening on that port.

Of course, you're wanting a programmatic way of accomplishing this and the GetTCPTable2 API is best as was already suggested. In fact, if you look at the IAT (Import Address Table) for netstat.exe, it actually uses that API to get that information.

There is a way to communicate directly with a command window and get its output using pipes and it would work fine, but the ideal way is to simply use the same API netstat uses.



Answered By - Daniel W. Elkins
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I open a TCP connection to a specific TCP port, send a string and read the response in Lazarus?

 October 22, 2022     freepascal, lazarus, sockets, tcp     No comments   

Issue

I'd like to do this without any external libraries if at all possible...

I want to open a TCP connection to a specific port on a specific IP address and then communicate by sending ANSI strings and receive an ANSI string response.

Sadly, I have no idea where to start with this, and searching the internet turns up what seem like pretty complex examples.

Can anyone give me any starting point?


Solution

You can use an excellent, free and multiplatform library called Synapse. It has built-in support for many protocols (FTP, HTTP, POP3, LDAP and so on), and it also allows you to implement your own protocols. You can write your own clients and servers with just few lines of code—amazing!

It has excellent debug capabilities, it's very fast and code efficient. Just look at the demos in the HOWTO area.

If you like detailed information regarding Synapse with Free Pascal and Lazarus look at Synapse (wiki).



Answered By - cezar
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, October 21, 2022

[FIXED] What does "connection reset by peer" mean?

 October 21, 2022     sockets, tcp     No comments   

Issue

What is the meaning of the "connection reset by peer" error on a TCP connection? Is it a fatal error or just a notification or related to the network failure?


Solution

It's fatal. The remote server has sent you a RST packet, which indicates an immediate dropping of the connection, rather than the usual handshake. This bypasses the normal half-closed state transition. I like this description:

"Connection reset by peer" is the TCP/IP equivalent of slamming the phone back on the hook. It's more polite than merely not replying, leaving one hanging. But it's not the FIN-ACK expected of the truly polite TCP/IP converseur.



Answered By - ire_and_curses
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What is the purpose of the `withFdSocket sock setCloseOnExecIfNeeded` call in Network.Socket example?

 October 21, 2022     haskell, network-programming, sockets, tcp     No comments   

Issue

In the Network.Socket package, there is an echo server example. In the echo server, a call to withFdSocket sock setCloseOnExecIfNeeded is made just before actually binding to the socket. The relevant function is below:

    open :: AddrInfo -> IO Socket
    open addr = E.bracketOnError (openSocket addr) close $ \sock -> do
        setSocketOption sock ReuseAddr 1
        withFdSocket sock setCloseOnExecIfNeeded
        bind sock $ addrAddress addr
        listen sock 1024
        return sock

The full example can be found on the Network.Socket package documentation.

What is the purpose of this call? It's my understanding that withFdSocket creates a file descriptor associated with the socket, and setCloseOnExecIfNeeded sets the CLOEXEC flag on the descriptor. However this descriptor is immediately 'discarded' and nothing is done with it.

Am I confused that the file descriptor always exists and withFdSocket just provides this existing descriptor, which we have to update with the flag in order for the socket to close when the program exits?


Solution

withFdSocket does not create an Fd; it just reads the one already stored inside the socket data structure.



Answered By - Daniel Wagner
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to get the number of client and the connect/disconnect events in Synapse ?

 October 21, 2022     ararat-synapse, delphi, indy, sockets, tcp     No comments   

Issue

I'm trying to use Synapse(TTCPBlockSocket) instead of Indy,but through the official help and demo i can't understand how to get the number of TCP client,and i didn't found the connect/disconnect events about Synapse,please give me some hint or sample code. Thanks in advance !


Solution

As TLama notes in the comments, each incoming connection shuold fire the OnStatus event with HR_Accept. If I look over the TBlockSocket source, each disconnect, either by protocol or by error, should fire an OnStatus event with the HR_SocketClose reason on the connection socket.



Answered By - Stijn Sanders
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, April 21, 2022

[FIXED] How do multiple clients connect simultaneously to one port, say 80, on a server?

 April 21, 2022     client-server, connection, http, port, tcp     No comments   

Issue

I understand the basics of how ports work. However, what I don't get is how multiple clients can simultaneously connect to say port 80. I know each client has a unique (for their machine) port. Does the server reply back from an available port to the client, and simply state the reply came from 80? How does this work?


Solution

First off, a "port" is just a number. All a "connection to a port" really represents is a packet which has that number specified in its "destination port" header field.

Now, there are two answers to your question, one for stateful protocols and one for stateless protocols.

For a stateless protocol (ie UDP), there is no problem because "connections" don't exist - multiple people can send packets to the same port, and their packets will arrive in whatever sequence. Nobody is ever in the "connected" state.

For a stateful protocol (like TCP), a connection is identified by a 4-tuple consisting of source and destination ports and source and destination IP addresses. So, if two different machines connect to the same port on a third machine, there are two distinct connections because the source IPs differ. If the same machine (or two behind NAT or otherwise sharing the same IP address) connects twice to a single remote end, the connections are differentiated by source port (which is generally a random high-numbered port).

Simply, if I connect to the same web server twice from my client, the two connections will have different source ports from my perspective and destination ports from the web server's. So there is no ambiguity, even though both connections have the same source and destination IP addresses.

Ports are a way to multiplex IP addresses so that different applications can listen on the same IP address/protocol pair. Unless an application defines its own higher-level protocol, there is no way to multiplex a port. If two connections using the same protocol simultaneously have identical source and destination IPs and identical source and destination ports, they must be the same connection.



Answered By - Borealid
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing