root/trunk/mysqlconnect.c

Revision 1646, 8.1 KB (checked in by Gary, 16 months ago)

unxsVZ fixed ugly mysqlconnect.c bug.

  • Property svn:keywords set to id
Line 
1/*
2FILE
3        $Id$
4PURPOSE
5        Wrapper for mysql_real_connect() that supports very fast
6        connect to main or alternative local.h set MySQL servers.
7AUTHOR
8        (C) 2010-2011 Gary Wallis for Unixservice, LLC.
9NOTES
10        Based on unxsBind/mysqlping.c test code.
11*/
12
13#include "mysqlrad.h"
14#include "local.h"
15#include <sys/socket.h>
16#include <arpa/inet.h>
17#include <netinet/in.h>
18#include <sys/types.h>
19#include <sys/select.h>
20#include <errno.h>
21
22//This is an important setting that depends on your network setup
23#define SELECT_TIMEOUT_USEC 300000
24
25//TOC protos
26void ConnectDb(void);
27unsigned TextConnectDb(void);
28
29
30void ConnectDb(void)
31{
32        //Handle quick cases first
33        //Port is irrelevant here. Make it clear.
34        mysql_init(&gMysql);
35        if(DBIP0==NULL)
36        {
37                if (mysql_real_connect(&gMysql,DBIP0,DBLOGIN,DBPASSWD,DBNAME,0,DBSOCKET,0))
38                        return;
39        }
40        if(DBIP1==NULL)
41        {
42                if (mysql_real_connect(&gMysql,DBIP1,DBLOGIN,DBPASSWD,DBNAME,0,DBSOCKET,0))
43                        return;
44        }
45
46        //Now we can use AF_INET/IPPROTO_TCP cases (TCP connections via IP number)
47        char cPort[16]={"3306"};//(*1)
48        int iSock,iConRes;
49        long lFcntlArg;
50        struct sockaddr_in sockaddr_inMySQLServer;
51        fd_set myset;
52        struct timeval tv;
53        int valopt;
54        socklen_t lon;
55
56        //Default port should really be gathered from a different source
57        //but for now we use the known MySQL server CentOS default port (*1).
58        if(DBPORT!=0)
59                sprintf(cPort,"%u",DBPORT);
60
61        if(DBIP0!=NULL)
62        {
63                if((iSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
64                        unxsVZ("Could not create ConnectDB() socket DBIP0");
65
66                // Set non-blocking
67                lFcntlArg=fcntl(iSock,F_GETFL,NULL);
68                lFcntlArg|=O_NONBLOCK;
69                fcntl(iSock,F_SETFL,lFcntlArg);
70
71                //DBIP0 has priority if we can create a connection we
72                //move forward immediately.
73                memset(&sockaddr_inMySQLServer,0,sizeof(sockaddr_inMySQLServer));
74                sockaddr_inMySQLServer.sin_family=AF_INET;
75                sockaddr_inMySQLServer.sin_addr.s_addr=inet_addr(DBIP0);
76                sockaddr_inMySQLServer.sin_port=htons(atoi(cPort));
77                iConRes=connect(iSock,(struct sockaddr *)&sockaddr_inMySQLServer,sizeof(sockaddr_inMySQLServer));
78                if(iConRes<0)
79                {
80                        if(errno==EINPROGRESS)
81                        {
82                                tv.tv_sec=0;
83                                tv.tv_usec=SELECT_TIMEOUT_USEC;
84                                FD_ZERO(&myset);
85                                FD_SET(iSock,&myset);
86                                if(select(iSock+1,NULL,&myset,NULL,&tv)>0)
87                                {
88                                        lon=sizeof(int);
89                                        getsockopt(iSock,SOL_SOCKET,SO_ERROR,(void*)(&valopt),&lon);
90                                        if(!valopt)
91                                        {
92                                                //Valid fast connection
93                                                close(iSock);//Don't need anymore.
94                                                if(mysql_real_connect(&gMysql,DBIP0,DBLOGIN,DBPASSWD,
95                                                                                        DBNAME,DBPORT,DBSOCKET,0))
96                                                        return;
97                                        }
98                                }
99                        }
100                }
101                close(iSock);//Don't need anymore.
102        }
103
104        if(DBIP1!=NULL)
105        {
106                if((iSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
107                        unxsVZ("Could not create ConnectDB() socket DBIP1");
108
109                // Set non-blocking
110                lFcntlArg=fcntl(iSock,F_GETFL,NULL);
111                lFcntlArg|=O_NONBLOCK;
112                fcntl(iSock,F_SETFL,lFcntlArg);
113
114                //Fallback to DBIP1
115                memset(&sockaddr_inMySQLServer,0,sizeof(sockaddr_inMySQLServer));
116                sockaddr_inMySQLServer.sin_family=AF_INET;
117                sockaddr_inMySQLServer.sin_addr.s_addr=inet_addr(DBIP1);
118                sockaddr_inMySQLServer.sin_port=htons(atoi(cPort));
119                iConRes=connect(iSock,(struct sockaddr *)&sockaddr_inMySQLServer,sizeof(sockaddr_inMySQLServer));
120                if(iConRes<0)
121                {
122                        if(errno==EINPROGRESS)
123                        {
124                                tv.tv_sec=0;
125                                tv.tv_usec=SELECT_TIMEOUT_USEC;
126                                FD_ZERO(&myset);
127                                FD_SET(iSock,&myset);
128                                if(select(iSock+1,NULL,&myset,NULL,&tv)>0)
129                                {
130                                        lon=sizeof(int);
131                                        getsockopt(iSock,SOL_SOCKET,SO_ERROR,(void*)(&valopt),&lon);
132                                        if(!valopt)
133                                        {
134                                                //Valid fast connection
135                                                close(iSock);//Don't need anymore.
136                                                if(mysql_real_connect(&gMysql,DBIP1,DBLOGIN,DBPASSWD,
137                                                                                        DBNAME,DBPORT,DBSOCKET,0))
138                                                        return;
139                                        }
140                                }
141                        }
142                }
143                close(iSock);//Don't need anymore.
144        }
145
146        //Failure exit 4 cases
147        char cMessage[256];
148        if(DBIP1!=NULL && DBIP0!=NULL)
149                sprintf(cMessage,"Could not connect to DBIP0:%1$s or DBIP1:%1$s\n",cPort);
150        else if(DBIP1==NULL && DBIP0==NULL)
151                sprintf(cMessage,"Could not connect to local socket\n");
152        else if(DBIP0!=NULL && DBIP1==NULL)
153                sprintf(cMessage,"Could not connect to DBIP0:%s or local socket (DBIP1)\n",cPort);
154        else if(DBIP0==NULL && DBIP1!=NULL)
155                sprintf(cMessage,"Could not connect to DBIP1:%s or local socket (DBIP0)\n",cPort);
156        else if(1)
157                sprintf(cMessage,"Could not connect unexpected case\n");
158
159        unxsVZ(cMessage);
160
161}//ConnectDb()
162
163
164unsigned TextConnectDb(void)
165{
166        //Handle quick cases first
167        //Port is irrelevant here. Make it clear.
168        mysql_init(&gMysql);
169        if(DBIP0==NULL)
170        {
171                if (mysql_real_connect(&gMysql,DBIP0,DBLOGIN,DBPASSWD,DBNAME,0,DBSOCKET,0))
172                        return(0);
173        }
174        if(DBIP1==NULL)
175        {
176                if (mysql_real_connect(&gMysql,DBIP1,DBLOGIN,DBPASSWD,DBNAME,0,DBSOCKET,0))
177                        return(0);
178        }
179
180        //Now we can use AF_INET/IPPROTO_TCP cases (TCP connections via IP number)
181        char cPort[16]={"3306"};//(*1)
182        int iSock,iConRes;
183        long lFcntlArg;
184        struct sockaddr_in sockaddr_inMySQLServer;
185        fd_set myset;
186        struct timeval tv;
187        int valopt;
188        socklen_t lon;
189
190        //Default port should really be gathered from a different source
191        //but for now we use the known MySQL server CentOS default port (*1).
192        if(DBPORT!=0)
193                sprintf(cPort,"%u",DBPORT);
194
195        if(DBIP0!=NULL)
196        {
197                if((iSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
198                {
199                        printf("Could not create TextConnectDB() socket DBIP0\n");
200                        return(1);
201                }
202
203                // Set non-blocking
204                lFcntlArg=fcntl(iSock,F_GETFL,NULL);
205                lFcntlArg|=O_NONBLOCK;
206                fcntl(iSock,F_SETFL,lFcntlArg);
207
208                //DBIP0 has priority if we can create a connection we
209                //move forward immediately.
210                memset(&sockaddr_inMySQLServer,0,sizeof(sockaddr_inMySQLServer));
211                sockaddr_inMySQLServer.sin_family=AF_INET;
212                sockaddr_inMySQLServer.sin_addr.s_addr=inet_addr(DBIP0);
213                sockaddr_inMySQLServer.sin_port=htons(atoi(cPort));
214                iConRes=connect(iSock,(struct sockaddr *)&sockaddr_inMySQLServer,sizeof(sockaddr_inMySQLServer));
215                if(iConRes<0)
216                {
217                        if(errno==EINPROGRESS)
218                        {
219                                tv.tv_sec=0;
220                                tv.tv_usec=SELECT_TIMEOUT_USEC;
221                                FD_ZERO(&myset);
222                                FD_SET(iSock,&myset);
223                                if(select(iSock+1,NULL,&myset,NULL,&tv)>0)
224                                {
225                                        lon=sizeof(int);
226                                        getsockopt(iSock,SOL_SOCKET,SO_ERROR,(void*)(&valopt),&lon);
227                                        if(!valopt)
228                                        {
229                                                //Valid fast connection
230                                                close(iSock);//Don't need anymore.
231                                                if(mysql_real_connect(&gMysql,DBIP0,DBLOGIN,DBPASSWD,
232                                                                                        DBNAME,DBPORT,DBSOCKET,0))
233                                                        return(0);
234                                        }
235                                }
236                        }
237                }
238                close(iSock);//Don't need anymore.
239        }
240
241        if(DBIP1!=NULL)
242        {
243                if((iSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
244                {
245                        printf("Could not create TextConnectDB() socket DBIP1\n");
246                        return(1);
247                }
248
249                // Set non-blocking
250                lFcntlArg=fcntl(iSock,F_GETFL,NULL);
251                lFcntlArg|=O_NONBLOCK;
252                fcntl(iSock,F_SETFL,lFcntlArg);
253
254                //Fallback to DBIP1
255                memset(&sockaddr_inMySQLServer,0,sizeof(sockaddr_inMySQLServer));
256                sockaddr_inMySQLServer.sin_family=AF_INET;
257                sockaddr_inMySQLServer.sin_addr.s_addr=inet_addr(DBIP1);
258                sockaddr_inMySQLServer.sin_port=htons(atoi(cPort));
259                iConRes=connect(iSock,(struct sockaddr *)&sockaddr_inMySQLServer,sizeof(sockaddr_inMySQLServer));
260                if(iConRes<0)
261                {
262                        if(errno==EINPROGRESS)
263                        {
264                                tv.tv_sec=0;
265                                tv.tv_usec=SELECT_TIMEOUT_USEC;
266                                FD_ZERO(&myset);
267                                FD_SET(iSock,&myset);
268                                if(select(iSock+1,NULL,&myset,NULL,&tv)>0)
269                                {
270                                        lon=sizeof(int);
271                                        getsockopt(iSock,SOL_SOCKET,SO_ERROR,(void*)(&valopt),&lon);
272                                        if(!valopt)
273                                        {
274                                                //Valid fast connection
275                                                close(iSock);//Don't need anymore.
276                                                if(mysql_real_connect(&gMysql,DBIP1,DBLOGIN,DBPASSWD,
277                                                                                        DBNAME,DBPORT,DBSOCKET,0))
278                                                        return(0);
279                                        }
280                                }
281                        }
282                }
283                close(iSock);//Don't need anymore.
284        }
285
286        //Failure exit 4 cases
287        char cMessage[256];
288        if(DBIP1!=NULL && DBIP0!=NULL)
289                sprintf(cMessage,"Could not connect to DBIP0:%1$s or DBIP1:%1$s\n",cPort);
290        else if(DBIP1==NULL && DBIP0==NULL)
291                sprintf(cMessage,"Could not connect to local socket\n");
292        else if(DBIP0!=NULL && DBIP1==NULL)
293                sprintf(cMessage,"Could not connect to DBIP0:%s or local socket (DBIP1)\n",cPort);
294        else if(DBIP0==NULL && DBIP1!=NULL)
295                sprintf(cMessage,"Could not connect to DBIP1:%s or local socket (DBIP0)\n",cPort);
296        else if(1)
297                sprintf(cMessage,"Could not connect unexpected case\n");
298
299        printf(cMessage);
300        return(1);
301
302}//unsigned TextConnectDb()
Note: See TracBrowser for help on using the browser.