So, after I got this error, I've been looking for an answer in here, almost everyone had a difficult way to fix this error but no one explained why this error occurs at all, so I don't find this question to be exactly duplicate.
I wrote a TCP socket in C and I used "getaddrinfo" function to make the socket work with hostnames, well it worked perfectly! you can find my codes on github.
but when I tried to create a UDP socket by "getaddrinfo" I got this error:
Servname not supported for ai_socktype
client.c
const char *host = argv[1];
const char *service = argv[2];
const char *string = argv[3];
struct addrinfo addrCriteria;
memset(&addrCriteria, 0, sizeof(addrCriteria));
addrCriteria.ai_family = AF_UNSPEC;
addrCriteria.ai_socktype = SOCK_DGRAM;
addrCriteria.ai_protocol = IPPROTO_UDP;
struct addrinfo *servAddr;
int ret = getaddrinfo(host, service, &addrCriteria, &servAddr);
if(ret != 0)
sysError(gai_strerror(ret));
I realized that when I give "service" a numeric input like 8080, no errors would return but when I use a string as service name like "tproxy" which points to port/8081, 'gai_strerror' returns mentioned error.
Obviously, gai_strerror says: "service names not supported for 'SOCK_DGRAM' socket types", but why? I mean the exact reason for "getaddrinfo" not supporting name services over UDP sockets?
Is there any other way to use service names with UDP sockets instead of port numbers? how?
TL;DR: There is no tproxy
UDP port.
If you look up the tproxy
service for UDP sockets in your service database,
getent services tproxy/udp
You get no output, because tproxy
is not an UDP service. If you look at all tproxy
services regardless of the protocol, getent services | grep -e tproxy
, you'll see
tproxy 8081/tcp
which means that tproxy
service is only defined for TCP protocol.
This means that if you ask getaddrinfo()
for an UDP socket for service 8081
, you will not find anything, because tproxy
is only defined for TCP and not UDP.
Compare to the case where you ask for and UDP socket for xmpp-client
service. At least my service database (getent services xmpp-client/udp
) responds with
xmpp-client 5222/udp jabber-client
and indeed, getaddrinfo()
happily provides the socket description for such UDP sockets (using xmpp-client
or jabber-client
as the service).
So, there are services like xmpp-client
that do have both TCP and UDP ports defined. On my system, getent services | grep -e xmpp-client
shows
xmpp-client 5222/tcp jabber-client
xmpp-client 5222/udp jabber-client
Because TCP and UDP are different protocols over IP, it makes sense that a service could use a different port number for TCP and UDP communications. So, it is unreasonable to assume that the service database should just return the same port numbers for TCP and UDP sockets.
In other words, you encounter the error because you mistakenly assume that because some service uses a TCP port, with a name registered in the service database, you should be able to use that name to specify an UDP port number, too.
TCP and UDP are separate protocols, and their port number spaces are separate. For example, TCP port 512 is used by the Unix exec
r-service, whereas UDP port 512 is used by the biff
mail notification service.