How to force client in UDP to open port when sending with sendto - sockets

I have simple server and client in UDP (WinSocks/C++).
I send datagram client -> server via sendto, and reply from server to client using the ip and port obtained from recvfrom function.
I found out that:
Every sendto from client is being sent from different port
When trying to reply from server Windows returns WSAECONNRESET (which mean that port is closed - http://support.microsoft.com/kb/263823)
How can I properly answer client from server (ie force port binding on client when sending using sendto?)
Edit: Adding some source code:
bool InitClient()
{
internal->sock = socket(PF_INET, SOCK_DGRAM, 0);
char8 yes = 1;
setsockopt(internal->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32));
return internal->sock != -1;
}
void Send(const IpAddress & target, const uint16 port, const char8 * data, int32 size )
{
sockaddr_in trgt;
memset(&trgt, 0, sizeof(trgt));
trgt.sin_family = AF_INET;
trgt.sin_port = htons(port);
trgt.sin_addr.s_addr = target.GetRaw();
if(sendto(internal->sock, (const char8 *)data, size, 0, (PSOCKADDR)&trgt, sizeof(trgt)) == SOCKET_ERROR)
{
LOG("Network sending error: %d", WSAGetLastError());
}
}

Call the "bind" function to specify a local port to send from. Example of using port 4567 below. Make sure to check the return value from bind.Call this code after you create the socket.
sockaddr_in local = {};
local.family = AF_INET;
local.port = htons(4567);
local.addr = INADDR_ANY;
bind(internal->sock,(sockaddr*)&local, sizeof(local));
If you bind to port zero instead of 4567 then the os will pick a random port for you and use it for all subsequent send and receives. You can call getsockname to discover which port the os picked for you after calling bind.

Related

getsockname() shows 127.0.0.1 after connect() to public IP

I'm struggling to make sense of this. The issue is seen on a machine that is:
Remote (I do not have access to it)
Running Windows 7
NOT running a proxy or VPN (or so I have been told)
My application has a snippet of code that tries to quickly determine which interface the OS prefers. It does the following:
// Create a socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
// Resolve DNS query
DWORD dwRemoteIp = GetHostAddr("www.google.com")
// I've simplified the call here, but "www.google.com" resolves to 172.217.3.100 in host byte order, so the resolution is correct
// Create the remote address to connect to
sockaddr_in remoteaddr = {0};
remoteaddr.sin_family = AF_INET;
remoteaddr.sin_addr.s_addr = htonl(dwRemoteIp);
remoteaddr.sin_port = htons(80);
// Connect the socket
if (0 == connect(sock, (struct sockaddr*)&remoteaddr, sizeof(remoteaddr))) {
// The connection succeeded -- see which local address was bound to
sockaddr_in localaddr = {0};
int len = sizeof(localaddr);
if (0 == getsockname(sock, (struct sockaddr*)&localaddr, (socklen_t *)&len)) {
// Here is where I see dwLocalIp == 0x7F000001, or 127.0.0.1
DWORD dwLocalIp = ntohl(localaddr.sin_addr.s_addr);
}
}
What could be going on here?

Create & send DHCP packets with source address 0.0.0.0 in Mac OS

I’m trying to create and send DHCP REQUEST message over a raw socket on Mac OS X. I’m able to create and send a well formatted message with the exception of the Source IP address. It should be 0.0.0.0.
Wireshark indicates the source address is whatever I set in the ip_src.s_addr field of the IP header, unless I use 0.0.0.0. When I use 0.0.0.0 Wireshark shows the IP as the machine sending the packet. FWIW, I can set destination IP to 255.255.255.255 no problem.
How do I set the source IP to 0.0.0.0?
Also what is the purpose of sin_addr.s_addr field used in sin parameter passed to the sendto function? Changing it or leaving it unset seems to have no effect.
Code:
int s = socket (PF_INET, SOCK_RAW, IPPROTO_RAW);
if (s < 0)
{
perror("Failed to create raw socket");
exit(1);
}
if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)
{
perror("Failed to set raw socket options");
exit(1);
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_BROADCAST;
sin.sin_port = htons(67);
inet_pton(AF_INET, "255.255.255.255", &sin.sin_addr);
if (sendto (s, DHCPPacket, DHCPPacketLength, 0, (struct sockaddr *) &sin, sizeof (struct sockaddr)) < 0)
{
perror("sendto failed");
exit(-1);
}
else
{
printf ("Packet Send. Length : %d Payload size: %d Options size: %d\n", DHCPPacketLength, sizeof(DHCPmsgType),sizeof(DHCP_VendorType));
}

Reset a TCP socket connection from application

How to reset an accepted socket in application level either with IO::Socket::INET in perl or in C?
There is a programm binding, listening on a TCP port, and accepts a client connection, after that it reads and writes some data.
If I simply close or shutdown the socket, TCP layer gracefully terminates (with FIN packet), rather than, I'd generate an RST packet.
You didn't specify the exact OS you are using. I found that Linux does have an API call which will reset a TCP connection, I have no idea how portable it is. The way to do it is to use the connect system call on the already connected socket but this time with family AF_UNSPEC.
After you have reset a socket that way it is even possible to connect the socket again with another connect call.
int main(int argc, char** argv)
{
int fd = socket(AF_INET6, SOCK_STREAM, 0);
while (1) {
struct sockaddr_in6 sockaddr = {
.sin6_family = AF_INET6,
.sin6_port = htons(80),
.sin6_flowinfo = 0,
.sin6_scope_id = 0,
};
struct timespec s = {
.tv_sec = 2,
.tv_nsec = 0,
};
/* Connect to port 80 on localhost */
inet_pton(AF_INET6, "::1", &sockaddr.sin6_addr.s6_addr);
connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr));
nanosleep(&s, NULL);
/* Reset previously connected socket */
sockaddr.sin6_family = AF_UNSPEC;
connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr));
nanosleep(&s, NULL);
}
}

How to make system choose port no for me in socket programming?

How to make system choose port no for me on the connect() call in c below is my code where i have used 5000 as port no the problem is every time i have to keep on changing the port no because it is throwing exception as ?
listen: Address already in use
How to get rid of this i want to fix the port no without making change in future is it possible?
int main(void)
{
int sockfd = 0,n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
memset(recvBuff, '0' ,sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000); //how to skip Address already in use?
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
Check in IANA Port number Listing, pick the which is not assigned or registered a prior. In your case port number 5000 is a TCP port already registered and used for commplex-main.
Note: Do not choose ports between 0 - 1023 as they are used by system processes.

Is it possible to use the same port and ip address?

I created a TCP server program which binds, listen and accepting a connection from the specific ip address and port number.
During the first connection : Server is accepting a SYN packet from the client and sending an ACK back to the client. Later getting a ACK from the client. Finally Client is RST with the server.
During the second connection the client is sending a SYN packet to the slave but there is no ACK from the server.
I think there is no binding is possible during the second connection with the same ip address and port number.
Is it possible to bind with the SAME ip address and port number in the second connection ?
server :
SOCKET sock;
SOCKET fd;
uint16 port = 52428;
// I am also using non blocking mode
void CreateSocket()
{
struct sockaddr_in server, client; // creating a socket address structure: structure contains ip address and port number
WORD wVersionRequested;
WSADATA wsaData;
int len;
int iResult;
u_long iMode = 1;
printf("Initializing Winsock\n");
wVersionRequested = MAKEWORD (1, 1);
iResult = WSAStartup (wVersionRequested, &wsaData);
if (iResult != NO_ERROR)
printf("Error at WSAStartup()\n");
// create socket
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
printf("Could not Create Socket\n");
//return 0;
}
printf("Socket Created\n");
iResult = ioctlsocket(sock, FIONBIO, &iMode);
if (iResult < 0)
printf("\n ioctl failed \n");
// create socket address of the server
memset( &server, 0, sizeof(server));
// IPv4 - connection
server.sin_family = AF_INET;
// accept connections from any ip adress
server.sin_addr.s_addr = htonl(INADDR_ANY);
// set port
server.sin_port = htons(52428);
//Binding between the socket and ip address
if(bind (sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
printf("Bind failed with error code: %d", WSAGetLastError());
}
//Listen to incoming connections
if(listen(sock, 10) == -1){
printf("Listen failed with error code: %d", WSAGetLastError());
}
printf("Server has been successfully set up - Waiting for incoming connections");
for(;;){
len = sizeof(client);
fd = accept(sock, (struct sockaddr*) &client, &len);
if (fd < 0){
printf("Accept failed");
closesocket(sock);
}
//echo(fd);
printf("\n Process incoming connection from (%s , %d)", inet_ntoa(client.sin_addr),ntohs(client.sin_port));
//closesocket(fd);
}
}
TCP connections are identified by four parameters:
Local IP
Local port
Remote IP
Remote port
The server normally uses the same Local IP and port for all its connections (e.g. an HTTP server listens on port 80 for all connection). Each connection from a client will have a different Remote IP and/or Remote port, and these resolve the ambiguity.
When the server closes all of its connected sockets, the TCB sticks around for several minutes in a TIME_WAIT state. This normally prevents a process from binding to the port, because you can't bind to a local IP/port that has any associated TCBs. If you want to restart the server and bind to the same port and address that it just used for connections, you need to use the SO_REUSEADDR socket option to get around this. See:
Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?
for details of this.