/*************************************************************************** * Copyright (C) 2013 by Blade_Arma * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #include #include #include #include #if defined _WINDOWS #include #else #include #include #include #include #include #endif #include "typedefs.h" #include "psemu_plugin_defs.h" #include "sio1.h" #include "connection.h" /***************************************************************************/ static int serversock = -1; static int clientsock = -1; static struct sockaddr_in address; static struct hostent *hostinfo; /***************************************************************************/ s32 connectionOpen() { switch(settings.player) { case PLAYER_MASTER: { int reuse_addr = 1; int one = 1; serversock = socket(AF_INET, SOCK_STREAM, 0); if(serversock == -1) { fprintf(stderr, "[SIO1] ERROR: server socket()\n"); return -1; } setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_addr, sizeof(reuse_addr)); setsockopt(serversock, IPPROTO_TCP, TCP_NODELAY, (const char*)&one, sizeof(one)); memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = settings.port; if(bind(serversock,(struct sockaddr*)&address,sizeof(address)) == -1) { fprintf(stderr, "[SIO1] ERROR: server bind()\n"); return -1; } if(listen(serversock, 1) != 0) { fprintf(stderr, "[SIO1] ERROR: server listen()\n"); return -1; } clientsock = -1; while(clientsock < 0) clientsock = accept(serversock, NULL, NULL); } break; case PLAYER_SLAVE: { int one = 1; memset(&address, 0, sizeof(address)); hostinfo = gethostbyname(settings.ip); address.sin_family = AF_INET; address.sin_addr = *((struct in_addr*)hostinfo->h_addr); address.sin_port = settings.port; clientsock = socket(AF_INET, SOCK_STREAM, 0); if(clientsock == -1) { fprintf(stderr, "[SIO1] ERROR: client socket()\n"); return -1; } setsockopt(clientsock, IPPROTO_TCP, TCP_NODELAY, (const char*)&one, sizeof(one)); if(connect(clientsock,(struct sockaddr*)&address,sizeof(address)) != 0) { fprintf(stderr, "[SIO1] ERROR: client connect(%s)\n", settings.ip); return -1; } } break; } return 0; } void connectionClose() { if(clientsock >= 0) { //close(clientsock); clientsock = -1; } if(serversock >= 0) { //close(serversock); serversock = -1; } } /***************************************************************************/ size_t connectionSend(u8 *pdata, s32 size) { size_t bytes = 0; if(clientsock >= 0) if((bytes = send(clientsock, (const char*)pdata, size, 0)) < 0) return 0; return bytes; } size_t connectionRecv(u8 *pdata, s32 size) { size_t bytes = 0; if(clientsock >= 0) if((bytes = recv(clientsock, (char*)pdata, size, 0)) < 0) return 0; return bytes; } /***************************************************************************/