Socket.c (4619B)
1 #include <EGong/Util/Socket.h> 2 #include <EGong/Util/Config.h> 3 #include <EGong/Util/Log.h> 4 #include <EGong/Packet.h> 5 6 #ifdef _WIN32 7 #include <windows.h> 8 #include <winsock2.h> 9 #include <ws2tcpip.h> 10 #include <iphlpapi.h> 11 #else 12 #include <sys/socket.h> 13 #include <sys/types.h> 14 #include <arpa/inet.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <unistd.h> 18 #include <netinet/in.h> 19 #endif 20 #include <fcntl.h> 21 #include <errno.h> 22 23 SOCKET EGong_listen_sock; 24 25 #ifdef _WIN32 26 WSADATA wsaData; 27 #endif 28 int inet_aton(const char *cp, struct in_addr *inp){ 29 inp->s_addr=inet_addr(cp); 30 if(inp->s_addr==-1){ 31 return 0; 32 } 33 else{ 34 return 1; 35 } 36 } 37 38 int EGong_sockets_setup(void){ 39 do_log("Setting up sockets...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 40 #ifdef _WIN32 41 int res=WSAStartup(MAKEWORD(2,2), &wsaData); 42 if(res!=0) { 43 do_log("WSAStartup failed", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL); 44 return -1; 45 } 46 #endif 47 return 0; 48 } 49 int EGong_sockets_shutdown(void){ 50 do_log("Shutting down sockets...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 51 #ifdef _WIN32 52 WSACleanup(); 53 #endif 54 return 0; 55 } 56 57 void EGong_socket_close(SOCKET *sock){ 58 #ifdef _WIN32 59 closesocket(*sock); 60 #else 61 close(*sock); 62 #endif 63 } 64 int EGong_socket_open(SOCKET *sock){ 65 do_log("Opening UDP-Socket...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 66 *sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 67 #ifdef _WIN32 68 if(*sock==INVALID_SOCKET){ 69 #else 70 if(*sock<0){ 71 #endif 72 do_log("Couldn't initialize socket",LOG_TYPE_SOCKET, LOG_LEVEL_ERROR); 73 EGong_socket_close(sock); 74 return -1; 75 } 76 return 0; 77 } 78 int EGong_sockaddr_init(struct sockaddr_in *addr, const char *ip, unsigned int port, sa_family_t family){ 79 memset(addr, 0, sizeof(*addr)); 80 if(inet_aton((char *)ip,&addr->sin_addr)<0){ 81 do_log("Couldn't convert bind address", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR); 82 return -1; 83 } 84 addr->sin_family = family; 85 addr->sin_port = htons(port); 86 return 0; 87 } 88 int EGong_listener_init(SOCKET *sock, struct EGong_config_server *config){ 89 struct sockaddr_in listen_server; 90 91 if(config==NULL) 92 config=&EGong_global_configuration.server; 93 if(sock==NULL) 94 sock=&EGong_listen_sock; 95 96 do_log("Initializing listener...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 97 if(EGong_socket_open(sock)<0){ 98 do_log("Couldn't open socket",LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 99 return -1; 100 } 101 #ifdef _WIN32 102 unsigned long nonblocking_long=1; 103 do_log("Setting socket nonblocking...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 104 if (ioctlsocket(*sock, FIONBIO, &nonblocking_long)==SOCKET_ERROR){ 105 do_log("Couldn't set listensocket nonblocking",LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR); 106 } 107 #endif 108 if(EGong_sockaddr_init(&listen_server, config->bind_ip.str.data, config->port, AF_INET)<0){ 109 do_log("Couldn't initialize address",LOG_TYPE_NORMAL, LOG_LEVEL_ERROR); 110 EGong_socket_close(sock); 111 return -2; 112 } 113 do_log("Binding socket...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 114 if(bind(*sock, (struct sockaddr *) &listen_server, sizeof(listen_server))<0){ 115 do_log("Couldn't bind to sock", LOG_TYPE_SOCKET, LOG_LEVEL_ERROR); 116 EGong_socket_close(sock); 117 return -3; 118 } 119 do_log("Listening on socket...",LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 120 return 0; 121 } 122 int EGong_listener_get(SOCKET *sock, char *dest, int length, struct sockaddr *source, int flags){ 123 if(sock==NULL) 124 sock=&EGong_listen_sock; 125 int ret; 126 socklen_t size=sizeof(*source); 127 if(source==NULL){ 128 struct sockaddr test; 129 source=&test; 130 } 131 do_log("Receiving on socket...",LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG); 132 #ifdef _WIN32 133 ret=recvfrom(*sock,dest,length, flags&(~MSG_DONTWAIT), source, &size); 134 if((flags&MSG_PEEK)>0&&ret==SOCKET_ERROR&&WSAGetLastError()==WSAEMSGSIZE){ 135 return length; 136 } 137 else if((flags&MSG_DONTWAIT)>0&&ret==SOCKET_ERROR&&(WSAGetLastError()==WSAEWOULDBLOCK)) { 138 #else 139 ret=recvfrom(*sock,dest,length, flags, source, &size); 140 if((flags&MSG_DONTWAIT)>0&&ret==-1&&(errno==EAGAIN||errno==EWOULDBLOCK)) { 141 #endif 142 return 0; 143 } 144 else if(ret<0){ 145 do_log("Couldn't receive from socket", LOG_TYPE_SOCKET, LOG_LEVEL_ERROR); 146 return -1; 147 } 148 return ret; 149 } 150 void EGong_listener_close(SOCKET *sock){ 151 if(sock==NULL){ 152 sock=&EGong_listen_sock; 153 } 154 EGong_socket_close(sock); 155 } 156 int EGong_sendto(SOCKET *sock, const char *dest, const char *msg, size_t msg_len, struct EGong_config_server *config){ 157 struct sockaddr_in server; 158 if(config==NULL) 159 config=&EGong_global_configuration.server; 160 EGong_sockaddr_init(&server, dest, config->port, AF_INET); 161 int ret=sendto(*sock, msg, msg_len, 0, (struct sockaddr *)&server, sizeof(server)); 162 if(ret!=msg_len){ 163 do_log("Error while sending message", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR); 164 } 165 return ret; 166 }