windows porting changes
[csql.git] / src / network / TCPServer.cxx
blob126d8e16d73f413d513488e43167cdad30ae9712
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include <os.h>
21 #include <CSql.h>
22 #include <Network.h>
23 #include <SqlNetworkHandler.h>
25 DbRetVal TCPServer::start()
27 DbRetVal rv = OK;
28 if (port == 0 )
30 printError(ErrBadArg, "Set the port first before starting\n");
31 return ErrBadArg;
33 struct sockaddr_in my_addr;
34 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
35 printError(ErrOS, "Unable to create socket\n");
36 return ErrOS;
38 my_addr.sin_family = AF_INET;
39 my_addr.sin_port = htons(port);
40 my_addr.sin_addr.s_addr = INADDR_ANY;
41 memset(&(my_addr.sin_zero), '\0', 8);
42 int on = 1;
43 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
44 (char *)&on, sizeof(on) );
47 if (bind(sockfd, (struct sockaddr *)&my_addr,
48 sizeof(struct sockaddr)) == -1) {
49 printError(ErrOS, "bind failed for port %d",port);
50 return ErrOS;
52 if (listen(sockfd, 10) == -1) {
53 printError(ErrOS, "listen failed");
54 return ErrOS;
56 return rv;
59 DbRetVal TCPServer::stop()
61 DbRetVal rv = OK;
62 close (sockfd);
63 return rv;
65 DbRetVal TCPServer::handleClient()
67 printf("DEBUG::handling client\n");
68 DbRetVal rv = OK;
69 socklen_t addressLen = sizeof(struct sockaddr);
70 clientfd = accept(sockfd, (struct sockaddr*) &clientAddress, (int*)&addressLen);
71 int ret = os::fork();
72 if (ret) {
73 //parent
74 close(clientfd);
75 return OK;
76 }else if (ret == 0) {
77 int on = 1;
78 setsockopt(clientfd, IPPROTO_TCP, TCP_NODELAY,
79 (char *)&on, sizeof(on) );
81 //child
82 int response = 1;
83 int ret = os::send(clientfd, &response, 4, 0);
84 if (ret == -1)
86 printError(ErrOS, "Unable to communicate to peer\n");
87 return ErrOS;
89 // printf("sent connect ack packet to client\n");
90 fd_set fdset;
91 struct timeval timeout;
92 SqlNetworkHandler handler;
93 handler.sockfd = clientfd;
94 PacketHeader header;
95 while(true) {
96 FD_ZERO(&fdset);
97 FD_SET(clientfd, &fdset);
98 timeout.tv_sec = 5;
99 timeout.tv_usec = 0;
100 int ret = os::select(clientfd+1, &fdset, 0, 0, &timeout);
101 if (ret > 0) {
102 // printf("something in fd\n");
103 int numbytes = os::recv(clientfd,&header,sizeof(PacketHeader),0);
104 if (!numbytes) {
105 close(clientfd);
106 handler.closeConnection();
107 exit(1);
109 if (numbytes == -1)
111 printError(ErrOS, "Error reading from socket");
112 handler.closeConnection();
113 exit(1);
115 // printf("HEADER says packet type is %d\n", header.packetType);
116 char *buffer = NULL;
117 if (header.packetType != SQL_NW_PKT_DISCONNECT &&
118 header.packetType != SQL_NW_PKT_COMMIT &&
119 header.packetType != SQL_NW_PKT_ROLLBACK &&
120 header.packetType != SQL_NW_PKT_FETCH &&
121 header.packetType != SQL_NW_PKT_SHOWTABLES &&
122 header.packetType != SQL_NW_PKT_LASTAIVAL )
124 buffer = (char*) malloc(header.packetLength);
125 numbytes = os::recv(clientfd,buffer,header.packetLength,0);
126 if (numbytes == -1)
128 printError(ErrOS, "Error reading from socket");
129 handler.closeConnection();
130 exit(1);
133 ResponsePacket *rpkt = (ResponsePacket *)
134 handler.process(header, buffer);
135 if (rpkt != NULL) rv = handler.servePacket(header, rpkt);
138 } else {
139 printError(ErrOS, "Unable to fork new process");
140 return ErrOS;
142 return OK;