summaryrefslogtreecommitdiff
path: root/src/udp.c
diff options
context:
space:
mode:
authororoborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e>2008-06-24 15:56:36 +0000
committeroroborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e>2008-06-24 15:56:36 +0000
commit826a768318d071200b289ed3a93ee409759dbae3 (patch)
tree3b3ade45833382db74ab0cb33d8d4327da672bfc /src/udp.c
parent13064d1bfc0459be37d8229f3f8c037fb8a10b8f (diff)
- podpora IPv6
- game server je schopny obsluhovat clientov zo sieti IPv4 a IPv6 sucastne - hrac si moze zvolit v nastaveniach, ci che pouzivat IPv4 alebo IPv6 - odkolnenie od SDL_net ( nepodporuje IPv6 ) // ale v kode este podpora SDL_Net je git-svn-id: http://opensvn.csie.org/tuxanci_ng@70 0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e
Diffstat (limited to 'src/udp.c')
-rw-r--r--src/udp.c221
1 files changed, 164 insertions, 57 deletions
diff --git a/src/udp.c b/src/udp.c
index d59902a..135b098 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -9,24 +9,21 @@
#include <string.h>
#include <stdio.h>
#include <netdb.h>
+#include <string.h>
#include <assert.h>
+#include <netdb.h>
#define BUFSIZE 1000
-
+#include "udp.h"
#include "main.h"
-typedef struct struct_sock_udp_t
-{
- int sock;
- struct sockaddr_in sockAddr;
-} sock_udp_t;
-
-sock_udp_t* newSockUdp()
+sock_udp_t* newSockUdp(int proto)
{
sock_udp_t *new;
new = malloc( sizeof(sock_udp_t) );
memset(new, 0, sizeof(sock_udp_t));
+ new->proto = proto;
return new;
}
@@ -37,30 +34,61 @@ void destroySockUdp(sock_udp_t *p)
free(p);
}
-sock_udp_t* bindUdpSocket(char *address, int port)
+sock_udp_t* bindUdpSocket(char *address, int port, int proto)
{
sock_udp_t *new;
+ int res;
assert( port > 0 && port < 65535 );
- new = newSockUdp();
+ new = newSockUdp(proto);
assert( new != NULL );
- if( ( new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0 )
+ if( new->proto == PROTO_UDPv4 )
+ {
+ new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ }
+
+#ifdef SUPPORT_IPv6
+ if( new->proto == PROTO_UDPv6 )
+ {
+ new->sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ }
+#endif
+
+ if( new->sock < 0 )
{
- fprintf(stderr, "nemozem obsadit sokcet !\n");
+ fprintf(stderr, "nemozem vytvorit socket !\n");
destroySockUdp(new);
return NULL;
}
- new->sockAddr.sin_family = AF_INET;
- new->sockAddr.sin_port = htons(port);
- new->sockAddr.sin_addr.s_addr = inet_addr(address);
+ memset(&(new->sockAddr), 0, sizeof(new->sockAddr));
+
+ if( new->proto == PROTO_UDPv4 )
+ {
+ new->sockAddr.sin_family = AF_INET;
+ new->sockAddr.sin_port = htons(port);
+ new->sockAddr.sin_addr.s_addr = inet_addr(address);
+
+ res = bind(new->sock, (struct sockaddr *)&(new->sockAddr), sizeof(new->sockAddr));
+ }
+
+#ifdef SUPPORT_IPv6
+ if( new->proto == PROTO_UDPv6 )
+ {
+ new->sockAddr6.sin6_family = AF_INET6;
+ new->sockAddr6.sin6_port = htons(port);
+ inet_pton(AF_INET6, address, &(new->sockAddr6.sin6_addr));
+
+ res = bind(new->sock, (struct sockaddr *)&(new->sockAddr6), sizeof(new->sockAddr6));
+ }
+#endif
- if( bind(new->sock, (struct sockaddr *)&(new->sockAddr), sizeof(new->sockAddr)) < 0 )
+ if( res < 0 )
{
- fprintf(stderr, "nemozem nastavit sokcet !\n");
+ fprintf(stderr, "nemozem nastavit sokcet %s %d !\n", address, port);
destroySockUdp(new);
return NULL;
}
@@ -68,30 +96,53 @@ sock_udp_t* bindUdpSocket(char *address, int port)
return new;
}
-sock_udp_t* connectUdpSocket(char *address, int port)
+sock_udp_t* connectUdpSocket(char *address, int port, int proto)
{
- struct hostent *host;
sock_udp_t *new;
assert( address != NULL );
assert( port > 0 && port < 65536 );
- new = newSockUdp();
+ new = newSockUdp(proto);
assert( new != NULL );
- if( ( new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0 )
+ if( new->proto == PROTO_UDPv4 )
+ {
+ new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ }
+
+#ifdef SUPPORT_IPv6
+ if( new->proto == PROTO_UDPv6 )
+ {
+ new->sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ }
+#endif
+
+ if( new->sock < 0 )
{
- fprintf(stderr, "nemozem sa pripojit na sokcet !\n");
+ fprintf(stderr, "nemozem vytvorit socket !\n");
destroySockUdp(new);
return NULL;
}
- host = gethostbyname(address);
- new->sockAddr.sin_family = AF_INET;
- new->sockAddr.sin_port = htons(port);
- memcpy(&(new->sockAddr.sin_addr), host->h_addr, host->h_length);
+ memset(&(new->sockAddr), 0, sizeof(new->sockAddr));
+
+ if( new->proto == PROTO_UDPv4 )
+ {
+ new->sockAddr.sin_family = AF_INET;
+ new->sockAddr.sin_port = htons(port);
+ new->sockAddr.sin_addr.s_addr = inet_addr(address);
+ }
+#ifdef SUPPORT_IPv6
+ if( new->proto == PROTO_UDPv6 )
+ {
+ new->sockAddr6.sin6_family = AF_INET6;
+ new->sockAddr6.sin6_port = htons(port);
+ inet_pton(AF_INET6, address, &(new->sockAddr6.sin6_addr));
+ }
+#endif
return new;
}
@@ -104,12 +155,31 @@ int readUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len)
assert( dst != NULL );
assert( address != NULL );
- addrlen = sizeof(src->sockAddr);
+ if( dst->proto == PROTO_UDPv4 )
+ {
+ addrlen = sizeof(src->sockAddr);
+
+ size = recvfrom(src->sock, address, len, 0,
+ (struct sockaddr *)&dst->sockAddr, (socklen_t *)&addrlen);
+ }
- if( ( size = recvfrom(src->sock, address, len, 0,
- (struct sockaddr *)&dst->sockAddr, (socklen_t *)&addrlen) ) < 0 )
+#ifdef SUPPORT_IPv6
+ if( dst->proto == PROTO_UDPv6 )
+ {
+ addrlen = sizeof(src->sockAddr6);
+
+ size = recvfrom(src->sock, address, len, 0,
+ (struct sockaddr *)&dst->sockAddr6, (socklen_t *)&addrlen);
+ }
+#endif
+
+ if( size < 0 )
{
- fprintf(stderr, "nemozem nacitat sokcet !\n");
+ char str_ip[STR_IP_SIZE];
+
+ getSockUdpIp(dst, str_ip, STR_IP_SIZE);
+
+ fprintf(stderr, "nemozem zapisat zo socketu %d %s %d!\n", size, str_ip, getSockUdpPort(dst));
return -1;
}
@@ -121,54 +191,87 @@ int writeUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len)
int addrlen;
int size;
-#ifdef DEBUG_LOST_PACKET
- if( rand() % DEBUG_LOST_PACKET == 0 )
+ assert( src != NULL );
+ assert( dst != NULL );
+ assert( address != NULL );
+
+ if( dst->proto == PROTO_UDPv4 )
+ {
+ addrlen = sizeof(src->sockAddr);
+
+ size = sendto(src->sock, address, len, 0,
+ (struct sockaddr *)&dst->sockAddr, (socklen_t)addrlen);
+ }
+
+#ifdef SUPPORT_IPv6
+ if( dst->proto == PROTO_UDPv6 )
{
- printf("debug lost packet %s\n", address);
- return size;
+ addrlen = sizeof(src->sockAddr6);
+
+ size = sendto(src->sock, address, len, 0,
+ (struct sockaddr *)&dst->sockAddr6, (socklen_t)addrlen);
}
#endif
- addrlen = sizeof(src->sockAddr);
+ if( size < 0 )
+ {
+ char str_ip[STR_IP_SIZE];
- assert( src != NULL );
- assert( dst != NULL );
- assert( address != NULL );
+ getSockUdpIp(dst, str_ip, STR_IP_SIZE);
- if( ( size = sendto(src->sock, address, len, 0,
- (struct sockaddr *)&dst->sockAddr, (socklen_t)addrlen) ) < 0 )
- {
- fprintf(stderr, "nemozem nacitat sokcet !\n");
+ fprintf(stderr, "nemozem zapisat na socket %d %s %d!\n", size, str_ip, getSockUdpPort(dst));
return -1;
- }
+ }
return size;
}
-void getSockUdpIp(sock_udp_t *p, char *str_ip)
+void getSockUdpIp(sock_udp_t *p, char *str_ip, int len)
{
assert( p != NULL );
assert( str_ip != NULL );
- strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr));
+ //strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr));
+
+ if( p->proto == PROTO_UDPv4 )
+ {
+ inet_ntop(AF_INET, &(p->sockAddr.sin_addr), str_ip, len);
+ }
+
+#ifdef SUPPORT_IPv6
+ if( p->proto == PROTO_UDPv6 )
+ {
+ inet_ntop(AF_INET6, &(p->sockAddr6.sin6_addr), str_ip, len);
+ }
+#endif
}
int getSockUdpPort(sock_udp_t *p)
{
assert( p != NULL );
- return htons(p->sockAddr.sin_port);
+
+ if( p->proto == PROTO_UDPv4 )
+ {
+ return htons(p->sockAddr.sin_port);
+ }
+
+#ifdef SUPPORT_IPv6
+ if( p->proto == PROTO_UDPv6 )
+ {
+ return htons(p->sockAddr6.sin6_port);
+ }
+#endif
+
+ assert( ! "bad proto !" );
+
+ return -1;
}
void closeUdpSocket(sock_udp_t *p)
{
- char str_ip[STR_IP_SIZE];
-
assert( p != NULL );
- getSockUdpIp(p, str_ip);
- printf("close connect from %s:%d\n", str_ip, htons(p->sockAddr.sin_port));
-
close(p->sock);
destroySockUdp(p);
}
@@ -203,7 +306,7 @@ static int myWait(sock_udp_t *p)
return 0;
}
-int test_udp_main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
sock_udp_t *sock;
char buf[BUFSIZE];
@@ -213,8 +316,11 @@ int test_udp_main(int argc, char *argv[])
{
sock_udp_t *cli;
- sock = bindUdpSocket( atoi(argv[2]) );
- cli = newSockUdp();
+ //sock = bindUdpSocket("::1", atoi(argv[2]), PROTO_UDPv6 );
+ sock = bindUdpSocket("127.0.0.1", atoi(argv[2]), PROTO_UDPv4 );
+
+ //cli = newSockUdp(PROTO_UDPv6);
+ cli = newSockUdp(PROTO_UDPv4);
while(1)
{
@@ -229,8 +335,9 @@ int test_udp_main(int argc, char *argv[])
if( strcmp(argv[1], "c") == 0 )
{
- sock = connectUdpSocket("127.0.0.1", atoi(argv[2]));
-
+ //sock = connectUdpSocket("::1", atoi(argv[2]), PROTO_UDPv6);
+ sock = connectUdpSocket("127.0.0.1", atoi(argv[2]), PROTO_UDPv4);
+
strcpy(buf, "Hello world !\n");
writeUdpSocket(sock, sock, buf, strlen(buf));
@@ -238,7 +345,7 @@ int test_udp_main(int argc, char *argv[])
readUdpSocket(sock, sock, buf, BUFSIZE);
printf("buf = %s", buf);
-
+ //while(1)sleep(1);
closeUdpSocket(sock);
}