diff options
| author | oroborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e> | 2008-06-24 15:56:36 +0000 |
|---|---|---|
| committer | oroborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e> | 2008-06-24 15:56:36 +0000 |
| commit | 826a768318d071200b289ed3a93ee409759dbae3 (patch) | |
| tree | 3b3ade45833382db74ab0cb33d8d4327da672bfc | |
| parent | 13064d1bfc0459be37d8229f3f8c037fb8a10b8f (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
| -rw-r--r-- | README.sk | 10 | ||||
| -rw-r--r-- | config.h | 5 | ||||
| -rw-r--r-- | include/client.h | 8 | ||||
| -rw-r--r-- | include/net_multiplayer.h | 6 | ||||
| -rw-r--r-- | include/screen_gameType.h | 1 | ||||
| -rw-r--r-- | include/server.h | 6 | ||||
| -rw-r--r-- | include/string_length.h | 2 | ||||
| -rw-r--r-- | include/udp.h | 16 | ||||
| -rw-r--r-- | server.conf | 6 | ||||
| -rwxr-xr-x | src/Makefile | 2 | ||||
| -rw-r--r-- | src/client.c | 4 | ||||
| -rw-r--r-- | src/net_multiplayer.c | 15 | ||||
| -rw-r--r-- | src/publicServer.c | 43 | ||||
| -rw-r--r-- | src/screen_gameType.c | 25 | ||||
| -rw-r--r-- | src/screen_world.c | 2 | ||||
| -rw-r--r-- | src/server.c | 144 | ||||
| -rw-r--r-- | src/udp.c | 221 |
17 files changed, 402 insertions, 114 deletions
@@ -91,7 +91,15 @@ Spustame server - konfiguracia servera je v server.conf, dufam, ze je jasna + konfiguracia servera je v server.conf : + + IP4 0.0.0.0 # IPv4 adresa + IP6 ::1 # IPv6 adresa + PORTv4 2200 # sietovy port pre IPv4 aredu + PORTv6 2206 # sietovy port pre IPv4 aredu + MAX_CLIENTS 32 # maximalny pocet clientov + ARENA FAGN # sietovy nazov areny + ************************************************ @@ -6,8 +6,9 @@ #define DEBUG_CLIENT_RECV */ -#define TUXANCI_NG_VERSION "svn69" +#define TUXANCI_NG_VERSION "svn70" #define DESTDIR "/usr/local/" -#define SUPPORT_NET_SDL_UDP +#define SUPPORT_NET_UNIX_UDP +//#define SUPPORT_NET_SDL_UDP //#define PUBLIC_SERVER diff --git a/include/client.h b/include/client.h index fe28eed..cd8c4c4 100644 --- a/include/client.h +++ b/include/client.h @@ -12,14 +12,8 @@ #endif -#ifdef SUPPORT_NET_UNIX_TCP -extern int initTcpClient(char *ip, int port); -extern void selectClientTcpSocket(); -extern void quitTcpClient(); -#endif - #ifdef SUPPORT_NET_UNIX_UDP -extern int initUdpClient(char *ip, int port); +extern int initUdpClient(char *ip, int port, int proto); extern void eventPingServer(); extern void selectClientUdpSocket(); extern void refreshPingServerAlive(); diff --git a/include/net_multiplayer.h b/include/net_multiplayer.h index 0127de8..2da7dea 100644 --- a/include/net_multiplayer.h +++ b/include/net_multiplayer.h @@ -23,7 +23,11 @@ #define LIMIT_BUFFER 10240 -extern int initNetMuliplayer(int type, char *ip, int port); +#ifdef PUBLIC_SERVER +extern int initNetMulitplayerPublicServer(char *ip4, int port4, char *ip6, int port6); +#endif + +extern int initNetMuliplayer(int type, char *ip, int port, int proto); extern int getNetTypeGame(); extern void eventNetMultiplayer(); extern void quitNetMultiplayer(); diff --git a/include/screen_gameType.h b/include/screen_gameType.h index dc25d48..1780e1c 100644 --- a/include/screen_gameType.h +++ b/include/screen_gameType.h @@ -9,6 +9,7 @@ extern void initScreenGameType(); extern int getSettingGameType(); extern char* getSettingIP(); extern int getSettingPort(); +extern int getSettingProto(); extern void quitScreenGameType(); #endif diff --git a/include/server.h b/include/server.h index 178dc34..247b836 100644 --- a/include/server.h +++ b/include/server.h @@ -51,9 +51,13 @@ typedef struct client_struct buffer_t *buffer; } client_t; +#ifdef PUBLIC_SERVER +extern int initUdpPublicServer(char *ip4, int port4, char *ip6, int port6); +#endif #ifdef SUPPORT_NET_UNIX_UDP -extern int initUdpServer(char *ip, int port); +extern int initUdpServer(char *ip, int port, int proto); +extern int initUdpServerMultiProto(char *ip4, char *ip6, int port4, int port6); extern client_t* newUdpClient(sock_udp_t *sock_udp); extern void selectServerUdpSocket(); extern void quitUdpServer(); diff --git a/include/string_length.h b/include/string_length.h index 243cb69..b1712ee 100644 --- a/include/string_length.h +++ b/include/string_length.h @@ -11,6 +11,6 @@ #define STR_NAME_SIZE 32 #define STR_PATH_SIZE 4096 #define STR_FILE_NAME_SIZE 256 -#define STR_IP_SIZE 24 +#define STR_IP_SIZE 64 #endif diff --git a/include/udp.h b/include/udp.h index ce89c53..29f383b 100644 --- a/include/udp.h +++ b/include/udp.h @@ -5,21 +5,27 @@ #define MY_UDP -#include "main.h" +#define SUPPORT_IPv6 + +#define PROTO_UDPv4 0 +#define PROTO_UDPv6 1 typedef struct struct_sock_udp_t { int sock; + int proto; + + struct sockaddr_in6 sockAddr6; struct sockaddr_in sockAddr; } sock_udp_t; -extern sock_udp_t* newSockUdp(); +extern sock_udp_t* newSockUdp(int proto); extern void destroySockUdp(sock_udp_t *p); -extern sock_udp_t* bindUdpSocket(char *address, int port); -extern sock_udp_t* connectUdpSocket(char *address, int port); +extern sock_udp_t* bindUdpSocket(char *address, int port, int proto); +extern sock_udp_t* connectUdpSocket(char *address, int port, int proto); extern int readUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len); extern int writeUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len); -extern void getSockUdpIp(sock_udp_t *p, char *str_ip); +extern void getSockUdpIp(sock_udp_t *p, char *str_ip, int len); extern int getSockUdpPort(sock_udp_t *p); extern void closeUdpSocket(sock_udp_t *p); diff --git a/server.conf b/server.conf index 1c24934..b9f080b 100644 --- a/server.conf +++ b/server.conf @@ -1,5 +1,7 @@ -IP 0.0.0.0 -PORT 2200 +IP4 0.0.0.0 +IP6 ::1 +PORTv4 2200 +PORTv6 2206 MAX_CLIENTS 32 ARENA FAGN diff --git a/src/Makefile b/src/Makefile index 29273cb..5a2a84d 100755 --- a/src/Makefile +++ b/src/Makefile @@ -16,7 +16,7 @@ FILES = interface.o space.o idManager.o storage.o font.o list.o modules.o\ item.o widget_label.o screen_mainMenu.o widget_button.o screen_analyze.o widget_textfield.o \ widget_check.o widget_image.o widget_select.o screen_setting.o screen_gameType.o screen_choiceArena.o \ widget_buttonimage.o screen_credits.o homeDirector.o screen_table.o \ - sdl_udp.o proto.o server.o client.o term.o keytable.o language.o game.o + sdl_udp.o udp.o proto.o server.o client.o term.o keytable.o language.o game.o tuxanci-ng: $(FILES) $(CC) $(CFLAGS) $(LIBS) -o $(BUILD_DIR)/tuxanci-ng $(BUILD_DIR)/*.o diff --git a/src/client.c b/src/client.c index 2210a3a..138caa0 100644 --- a/src/client.c +++ b/src/client.c @@ -44,9 +44,9 @@ static void initClient() #ifdef SUPPORT_NET_UNIX_UDP -int initUdpClient(char *ip, int port) +int initUdpClient(char *ip, int port, int proto) { - sock_server_udp = connectUdpSocket(ip, port); + sock_server_udp = connectUdpSocket(ip, port, proto); if( sock_server_udp == NULL ) { diff --git a/src/net_multiplayer.c b/src/net_multiplayer.c index 92e9504..a9132e3 100644 --- a/src/net_multiplayer.c +++ b/src/net_multiplayer.c @@ -31,7 +31,16 @@ int getNetTypeGame() return netGameType; } -int initNetMuliplayer(int type, char *ip, int port) +#ifdef PUBLIC_SERVER + +int initNetMulitplayerPublicServer(char *ip4, int port4, char *ip6, int port6) +{ + netGameType = NET_GAME_TYPE_SERVER; + return initUdpPublicServer(ip4, port4, ip6, port6); +} +#endif + +int initNetMuliplayer(int type, char *ip, int port, int proto) { netGameType = type; @@ -42,7 +51,7 @@ int initNetMuliplayer(int type, char *ip, int port) case NET_GAME_TYPE_SERVER : #ifdef SUPPORT_NET_UNIX_UDP - if( initUdpServer(ip, port) != 0 ) + if( initUdpServer(ip, port, proto) != 0 ) { fprintf(stderr, "Neomzem inicalizovat sietovu hru pre server !\n"); netGameType = NET_GAME_TYPE_NONE; @@ -62,7 +71,7 @@ int initNetMuliplayer(int type, char *ip, int port) #ifndef PUBLIC_SERVER case NET_GAME_TYPE_CLIENT : #ifdef SUPPORT_NET_UNIX_UDP - if( initUdpClient(ip, port) != 0 ) + if( initUdpClient(ip, port, proto) != 0 ) { fprintf(stderr, "Neomzem inicalizovat sietovu hru pre clienta !\n"); netGameType = NET_GAME_TYPE_NONE; diff --git a/src/publicServer.c b/src/publicServer.c index 93ed2a7..7407f3f 100644 --- a/src/publicServer.c +++ b/src/publicServer.c @@ -35,8 +35,46 @@ static char *getSetting(char *env, char *param, char *default_val) return getParamElse(param, getServerConfigFileValue(env, default_val) ); } +static int initPublicServerNetwork() +{ + char ip4[STR_IP_SIZE]; + char ip6[STR_IP_SIZE]; + char *p_ip4, *p_ip6; + int port4; + int port6; + int ret; + + ret = -1; + + strcpy(ip4, getSetting("IP4", "--ip4", "none" ) ); + strcpy(ip6, getSetting("IP6", "--ip6", "none" ) ); + + p_ip4 = ip4; + + if( strcmp(ip4, "none") == 0 ) + { + p_ip4 = NULL; + } + + p_ip6 = ip6; + + if( strcmp(ip6, "none") == 0 ) + { + p_ip6= NULL; + } + + port4 = atoi( getSetting("PORTv4", "--port", "2200") ); + port6 = atoi( getSetting("PORTv6", "--port", "2200") ); + + ret = initNetMulitplayerPublicServer(p_ip4, port4, p_ip6, port6); + + return ret; +} + int initPublicServer() { + int ret; + initListID(); initModule(); initArenaFile(); @@ -53,8 +91,9 @@ int initPublicServer() addNewItem(arena->spaceItem, ID_UNKNOWN); isSignalEnd = FALSE; - if( initNetMuliplayer(NET_GAME_TYPE_SERVER, - getSetting("IP", "--ip", "0.0.0.0") , atoi( getSetting("PORT", "--port", "2200") ) ) < 0 ) + ret = initPublicServerNetwork(); + + if( ret < 0 ) { printf("Nemozem inicalizovat sietovy socket !\n"); return -1; diff --git a/src/screen_gameType.c b/src/screen_gameType.c index da0e73e..814c9c8 100644 --- a/src/screen_gameType.c +++ b/src/screen_gameType.c @@ -16,6 +16,7 @@ #include "list.h" #include "screen_setting.h" #include "tux.h" +#include "udp.h" #include "widget_label.h" #include "widget_button.h" @@ -31,6 +32,7 @@ static widget_button_t *button_play; static widget_label_t *label_none; static widget_label_t *label_server; static widget_label_t *label_client; +static widget_label_t *label_ipv6; static widget_label_t *label_ip; static widget_label_t *label_port; @@ -39,6 +41,8 @@ static widget_check_t *check_none; static widget_check_t *check_server; static widget_check_t *check_client; +static widget_check_t *check_ipv6; + static widget_textfield_t *textfield_ip; static widget_textfield_t *textfield_port; @@ -55,33 +59,30 @@ void drawScreenGameType() drawWidgetLabel(label_server); drawWidgetLabel(label_client); - if( check_client->status == TRUE ) - { - drawWidgetLabel(label_ip); - drawWidgetTextfield(textfield_ip); - } - if( check_none->status == FALSE ) { drawWidgetLabel(label_port); drawWidgetTextfield(textfield_port); + drawWidgetLabel(label_ip); + drawWidgetTextfield(textfield_ip); + drawWidgetCheck(check_ipv6); + drawWidgetLabel(label_ipv6); } drawWidgetCheck(check_none); drawWidgetCheck(check_server); drawWidgetCheck(check_client); - drawWidgetButton(button_back); drawWidgetButton(button_play); } void eventScreenGameType() { - eventWidgetCheck(check_none); eventWidgetCheck(check_server); eventWidgetCheck(check_client); + eventWidgetCheck(check_ipv6); eventWidgetTextfield(textfield_ip); eventWidgetTextfield(textfield_port); @@ -181,6 +182,9 @@ void initScreenGameType() textfield_ip = newWidgetTextfield(getParamElse("--ip", "127.0.0.1"), 300, 180); textfield_port = newWidgetTextfield(getParamElse("--port", "2200"), 300, 280); + check_ipv6 = newWidgetCheck(300, 330, FALSE, eventWidget); + label_ipv6 = newWidgetLabel("support IPv6", 330, 325, WIDGET_LABEL_LEFT); + registerScreen( newScreen("gameType", startScreenGameType, eventScreenGameType, drawScreenGameType, stopScreenGameType) ); } @@ -217,6 +221,11 @@ int getSettingPort() return atoi( textfield_port->text ); } +int getSettingProto() +{ + return ( check_ipv6->status == TRUE ? PROTO_UDPv6 : PROTO_UDPv4 ); +} + void quitScreenGameType() { destroyWidgetImage(image_backgorund); diff --git a/src/screen_world.c b/src/screen_world.c index a5fdc1c..f889471 100644 --- a/src/screen_world.c +++ b/src/screen_world.c @@ -55,7 +55,7 @@ void setGameType() { int ret = 0; - ret = initNetMuliplayer( getSettingGameType(), getSettingIP(), getSettingPort() ); + ret = initNetMuliplayer( getSettingGameType(), getSettingIP(), getSettingPort(), getSettingProto() ); if( ret != 0 ) { diff --git a/src/server.c b/src/server.c index bda983a..1f42774 100644 --- a/src/server.c +++ b/src/server.c @@ -33,6 +33,7 @@ #ifdef SUPPORT_NET_UNIX_UDP #include "udp.h" static sock_udp_t *sock_server_udp; +static sock_udp_t *sock_server_udp_second; #endif #ifdef SUPPORT_NET_SDL_UDP @@ -175,9 +176,10 @@ void static initServer() } #ifdef SUPPORT_NET_UNIX_UDP -int initUdpServer(char *ip, int port) +int initUdpServer(char *ip, int port, int proto) { - sock_server_udp = bindUdpSocket(ip, port); + sock_server_udp = bindUdpSocket(ip, port, proto); + sock_server_udp_second = NULL; if( sock_server_udp == NULL ) { @@ -192,6 +194,44 @@ int initUdpServer(char *ip, int port) } #endif +#ifdef PUBLIC_SERVER + +int initUdpPublicServer(char *ip4, int port4, char *ip6, int port6) +{ + sock_server_udp = NULL; + sock_server_udp_second = NULL; + + if( ip4 != NULL ) + { + sock_server_udp = bindUdpSocket(ip4, port4, PROTO_UDPv4); + + if( sock_server_udp == NULL ) + { + return -1; + } + + printf("server listen UDP port %s %d\n", ip4, port4); + } + + if( ip6 != NULL ) + { + sock_server_udp_second = bindUdpSocket(ip6, port6, PROTO_UDPv6); + + if( sock_server_udp_second == NULL ) + { + return -1; + } + + printf("server listen UDP port %s %d\n", ip6, port6); + } + + initServer(); + + return 0; +} + +#endif + #ifdef SUPPORT_NET_SDL_UDP int initSdlUdpServer(int port) { @@ -233,8 +273,8 @@ client_t* newUdpClient(sock_udp_t *sock_udp) assert( sock_udp != NULL ); - getSockUdpIp(sock_udp, str_ip); - printf("new client from %s:%d\n", str_ip, getSockUdpPort(sock_udp)); + getSockUdpIp(sock_udp, str_ip, STR_IP_SIZE); + printf("new client from %s %d\n", str_ip, getSockUdpPort(sock_udp)); new = newAnyClient(); new->socket_udp = sock_udp; @@ -260,10 +300,13 @@ client_t* newSdlUdpClient(sock_sdl_udp_t *sock_sdl_udp) void destroyClient(client_t *p) { -// int index; + char str_ip[STR_IP_SIZE]; assert( p != NULL ); + getSockUdpIp(p->socket_udp, str_ip, STR_IP_SIZE); + printf("close connect %s %d\n", str_ip, getSockUdpPort(p->socket_udp) ); + #ifdef SUPPORT_NET_UNIX_UDP closeUdpSocket(p->socket_udp); #endif @@ -275,16 +318,11 @@ void destroyClient(client_t *p) destroyBuffer(p->buffer); destroyCheckFront(p->listCheck); - if( p->tux != NULL ) { #ifdef PUBLIC_SERVER addPlayerInHighScore(p->tux->name, p->tux->score); #endif -/* - index = searchListItem(getCurrentArena()->listTux, p->tux); - delListItem(getCurrentArena()->listTux, index, destroyTux); -*/ delObjectFromSpaceWithObject(getCurrentArena()->spaceTux, p->tux, destroyTux); } @@ -323,7 +361,15 @@ void sendClient(client_t *p, char *msg) #endif #ifdef SUPPORT_NET_UNIX_UDP - ret = writeUdpSocket(sock_server_udp, p->socket_udp, msg, strlen(msg)); + if( p->socket_udp->proto == PROTO_UDPv4 ) + { + ret = writeUdpSocket(sock_server_udp, p->socket_udp, msg, strlen(msg)); + } + + if( p->socket_udp->proto == PROTO_UDPv6 ) + { + ret = writeUdpSocket(sock_server_udp_second, p->socket_udp, msg, strlen(msg)); + } #endif #ifdef SUPPORT_NET_SDL_UDP @@ -637,7 +683,7 @@ static void eventClientUdpSelect(sock_udp_t *sock_server) assert( sock_server != NULL ); - sock_client = newSockUdp(); + sock_client = newSockUdp(sock_server->proto); isCreateNewClient = FALSE; memset(buffer, 0, STR_SIZE); @@ -687,6 +733,7 @@ void selectServerUdpSocket() { struct timeval tv; fd_set readfds; + fd_set errorfds; int max_fd; int ret; @@ -701,27 +748,74 @@ void selectServerUdpSocket() #endif FD_ZERO(&readfds); - FD_SET(sock_server_udp->sock, &readfds); - max_fd = sock_server_udp->sock; + FD_ZERO(&errorfds); + + max_fd = 0; + + if( sock_server_udp != NULL ) + { + FD_SET(sock_server_udp->sock, &errorfds); + FD_SET(sock_server_udp->sock, &readfds); + + if( sock_server_udp->sock > max_fd ) + { + max_fd = sock_server_udp->sock; + } + } + + if( sock_server_udp_second != NULL ) + { + FD_SET(sock_server_udp_second->sock, &readfds); + FD_SET(sock_server_udp_second->sock, &errorfds); + + if( sock_server_udp_second->sock > max_fd ) + { + max_fd = sock_server_udp_second->sock; + } + } + + //printf("select..\n"); if( listClient->count == 0 ) { - ret = select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, NULL); + ret = select(max_fd+1, &readfds, (fd_set *)NULL, &errorfds, &tv); setServerTimer(); } else { - ret = select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); + ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv); } if( ret < 0 ) { + //printf("select ret = %d\n", ret); return; } - if( FD_ISSET(sock_server_udp->sock, &readfds) ) + if( sock_server_udp != NULL ) + { + if( FD_ISSET(sock_server_udp->sock, &readfds) ) + { + eventClientUdpSelect(sock_server_udp); + } + + if( FD_ISSET(sock_server_udp->sock, &errorfds) ) + { + printf("error\n"); + } + } + + if( sock_server_udp_second != NULL ) { - eventClientUdpSelect(sock_server_udp); + if( FD_ISSET(sock_server_udp_second->sock, &readfds) ) + { + eventClientUdpSelect(sock_server_udp_second); + } + + if( FD_ISSET(sock_server_udp_second->sock, &errorfds) ) + { + printf("error\n"); + } } } @@ -825,6 +919,7 @@ void eventServer() static void quitServer() { proto_send_end_server(PROTO_SEND_ALL, NULL); + assert( listClient != NULL ); destroyListItem(listClient, destroyClient); destroyTimer(listServerTimer); @@ -836,8 +931,17 @@ void quitUdpServer() { quitServer(); - assert( sock_server_udp != NULL ); - closeUdpSocket(sock_server_udp); + if( sock_server_udp != NULL ) + { + printf("close port %d\n", getSockUdpPort(sock_server_udp)); + closeUdpSocket(sock_server_udp); + } + + if( sock_server_udp_second != NULL ) + { + printf("close port %d\n", getSockUdpPort(sock_server_udp_second)); + closeUdpSocket(sock_server_udp_second); + } printf("quit UDP port\n"); } @@ -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); } |