libdrizzle Developer Documentation

conn.c
Go to the documentation of this file.
1/*
2 * Drizzle Client & Protocol Library
3 *
4 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5 * All rights reserved.
6 *
7 * Use and distribution licensed under the BSD license. See
8 * the COPYING file in this directory for full text.
9 */
10
16#include "common.h"
17
32
35/*
36 * Common Definitions
37 */
38
40{
41 return con->fd;
42}
43
45{
47
48 con->fd= fd;
49
50 ret= _con_setsockopt(con);
51 if (ret != DRIZZLE_RETURN_OK)
52 con->drizzle->last_errno= errno;
53
54 return ret;
55}
56
58{
59 if (con->fd == -1)
60 return;
61
62 (void)close(con->fd);
63 con->fd= -1;
64
66 con->packet_number= 0;
67 con->buffer_ptr= con->buffer;
68 con->buffer_size= 0;
69 con->events= 0;
70 con->revents= 0;
71
73}
74
76{
78
79 if ((con->events | events) == con->events)
80 return DRIZZLE_RETURN_OK;
81
82 con->events|= events;
83
84 if (con->drizzle->event_watch_fn != NULL)
85 {
86 ret= con->drizzle->event_watch_fn(con, con->events,
88 if (ret != DRIZZLE_RETURN_OK)
89 {
91 return ret;
92 }
93 }
94
95 return DRIZZLE_RETURN_OK;
96}
97
99{
101
102 if (revents != 0)
104
105 con->revents= revents;
106
107 /* Remove external POLLOUT watch if we didn't ask for it. Otherwise we spin
108 forever until another POLLIN state change. This is much more efficient
109 than removing POLLOUT on every state change since some external polling
110 mechanisms need to use a system call to change flags (like Linux epoll). */
111 if (revents & POLLOUT && !(con->events & POLLOUT) &&
112 con->drizzle->event_watch_fn != NULL)
113 {
114 ret= con->drizzle->event_watch_fn(con, con->events,
116 if (ret != DRIZZLE_RETURN_OK)
117 {
119 return ret;
120 }
121 }
122
123 con->events&= (short)~revents;
124
125 return DRIZZLE_RETURN_OK;
126}
127
129{
130 return con->drizzle;
131}
132
133const char *drizzle_con_error(const drizzle_con_st *con)
134{
135 return drizzle_error(con->drizzle);
136}
137
139{
140 return drizzle_errno(con->drizzle);
141}
142
144{
145 return drizzle_error_code(con->drizzle);
146}
147
149{
150 return drizzle_sqlstate(con->drizzle);
151}
152
157
159 drizzle_con_options_t options)
160{
161 con->options= options;
162}
163
165 drizzle_con_options_t options)
166{
167 con->options|= options;
168
169 /* If asking for the experimental Drizzle protocol, clean the MySQL flag. */
172}
173
175 drizzle_con_options_t options)
176{
177 con->options&= ~options;
178}
179
180const char *drizzle_con_host(const drizzle_con_st *con)
181{
183 {
184 if (con->socket.tcp.host == NULL && !(con->options & DRIZZLE_CON_LISTEN))
186
187 return con->socket.tcp.host;
188 }
189
190 return NULL;
191}
192
193in_port_t drizzle_con_port(const drizzle_con_st *con)
194{
196 {
197 if (con->socket.tcp.port != 0)
198 return con->socket.tcp.port;
199
200 if (con->options & DRIZZLE_CON_MYSQL)
202
204 }
205
206 return 0;
207}
208
209void drizzle_con_set_tcp(drizzle_con_st *con, const char *host, in_port_t port)
210{
212
214
215 if (host == NULL)
216 con->socket.tcp.host= NULL;
217 else
218 {
219 con->socket.tcp.host= con->socket.tcp.host_buffer;
220 strncpy(con->socket.tcp.host, host, NI_MAXHOST);
221 con->socket.tcp.host[NI_MAXHOST - 1]= 0;
222 }
223
224 con->socket.tcp.port= port;
225}
226
227const char *drizzle_con_user(const drizzle_con_st *con)
228{
229 return con->user;
230}
231
233{
234 return con->password;
235}
236
237void drizzle_con_set_auth(drizzle_con_st *con, const char *user,
238 const char *password)
239{
240 if (user == NULL)
241 con->user[0]= 0;
242 else
243 {
244 strncpy(con->user, user, DRIZZLE_MAX_USER_SIZE);
245 con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
246 }
247
248 if (password == NULL)
249 con->password[0]= 0;
250 else
251 {
252 strncpy(con->password, password, DRIZZLE_MAX_PASSWORD_SIZE);
254 }
255}
256
257const char *drizzle_con_db(const drizzle_con_st *con)
258{
259 return con->db;
260}
261
262void drizzle_con_set_db(drizzle_con_st *con, const char *db)
263{
264 if (db == NULL)
265 con->db[0]= 0;
266 else
267 {
268 strncpy(con->db, db, DRIZZLE_MAX_DB_SIZE);
269 con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
270 }
271}
272
274{
275 return con->context;
276}
277
279{
280 con->context= context;
281}
282
288
290{
291 return con->protocol_version;
292}
293
295{
296 return con->server_version;
297}
298
300{
301 uint32_t major;
302 uint32_t minor;
303 uint32_t version;
304 const char *current;
305 char *end;
306
307 current= con->server_version;
308
309 major= (uint32_t)strtoul(current, &end, 10);
310 current= end + 1;
311 minor= (uint32_t)strtoul(current, &end, 10);
312 current= end + 1;
313 version= (uint32_t)strtoul(current, &end, 10);
314
315 return (major * 10000) + (minor * 100) + version;
316}
317
319{
320 return con->thread_id;
321}
322
323const uint8_t *drizzle_con_scramble(const drizzle_con_st *con)
324{
325 return con->scramble;
326}
327
332
334{
335 return con->charset;
336}
337
339{
340 return con->status;
341}
342
344{
345 return con->max_packet_size;
346}
347
348/*
349 * Client Definitions
350 */
351
371
373 drizzle_result_st *result,
374 drizzle_return_t *ret_ptr)
375{
376 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUIT, NULL, 0,
377 0, ret_ptr);
378}
379
381 drizzle_result_st *result,
382 drizzle_return_t *ret_ptr)
383{
384 return drizzle_con_quit(con, result, ret_ptr);
385}
386
388 drizzle_result_st *result,
389 const char *db,
390 drizzle_return_t *ret_ptr)
391{
392 drizzle_con_set_db(con, db);
394 db, strlen(db), strlen(db), ret_ptr);
395}
396
398 drizzle_result_st *result,
399 const char *db,
400 drizzle_return_t *ret_ptr)
401{
402 return drizzle_con_select_db(con, result, db, ret_ptr);
403}
404
406 drizzle_result_st *result,
407 drizzle_return_t *ret_ptr)
408{
409 if (con->options & DRIZZLE_CON_MYSQL)
410 {
412 "0", 1, 1, ret_ptr);
413 }
414
415 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN, NULL,
416 0, 0, ret_ptr);
417}
418
420 drizzle_result_st *result, uint32_t level,
421 drizzle_return_t *ret_ptr)
422{
423 (void) level;
424 return drizzle_con_shutdown(con, result, ret_ptr);
425}
426
428 drizzle_result_st *result,
429 drizzle_return_t *ret_ptr)
430{
431 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_PING, NULL, 0,
432 0, ret_ptr);
433}
434
436 drizzle_result_st *result,
437 drizzle_return_t *ret_ptr)
438{
439 return drizzle_con_ping(con, result, ret_ptr);
440}
441
443 drizzle_result_st *result,
444 drizzle_command_t command,
445 const void *data, size_t size,
446 size_t total,
447 drizzle_return_t *ret_ptr)
448{
449 if (!(con->options & DRIZZLE_CON_READY))
450 {
452 {
453 drizzle_set_error(con->drizzle, "drizzle_command_write",
454 "connection not ready");
455 *ret_ptr= DRIZZLE_RETURN_NOT_READY;
456 return result;
457 }
458
459 *ret_ptr= drizzle_con_connect(con);
460 if (*ret_ptr != DRIZZLE_RETURN_OK)
461 return result;
462 }
463
464 if (drizzle_state_none(con))
465 {
467 con->result= NULL;
468 else
469 {
470 con->result= drizzle_result_create(con, result);
471 if (con->result == NULL)
472 {
473 *ret_ptr= DRIZZLE_RETURN_MEMORY;
474 return NULL;
475 }
476 }
477
478 con->command= command;
479 con->command_data= (uint8_t *)data;
480 con->command_size= size;
481 con->command_offset= 0;
482 con->command_total= total;
483
485 }
486 else if (con->command_data == NULL)
487 {
488 con->command_data= (uint8_t *)data;
489 con->command_size= size;
490 }
491
492 *ret_ptr= drizzle_state_loop(con);
493 if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
494 *ret_ptr= DRIZZLE_RETURN_OK;
495 else if (*ret_ptr != DRIZZLE_RETURN_OK &&
496 *ret_ptr != DRIZZLE_RETURN_IO_WAIT &&
497 *ret_ptr != DRIZZLE_RETURN_ERROR_CODE)
498 {
500 con->result= result;
501 }
502
503 return con->result;
504}
505
506/*
507 * Server Definitions
508 */
509
523
525{
526 return con->backlog;
527}
528
530{
531 con->backlog= backlog;
532}
533
535 uint8_t protocol_version)
536{
537 con->protocol_version= protocol_version;
538}
539
541 const char *server_version)
542{
543 if (server_version == NULL)
544 con->server_version[0]= 0;
545 else
546 {
547 strncpy(con->server_version, server_version,
550 }
551}
552
553void drizzle_con_set_thread_id(drizzle_con_st *con, uint32_t thread_id)
554{
555 con->thread_id= thread_id;
556}
557
558void drizzle_con_set_scramble(drizzle_con_st *con, const uint8_t *scramble)
559{
560 if (scramble == NULL)
561 con->scramble= NULL;
562 else
563 {
564 con->scramble= con->scramble_buffer;
565 memcpy(con->scramble, scramble, DRIZZLE_MAX_SCRAMBLE_SIZE);
566 }
567}
568
570 drizzle_capabilities_t capabilities)
571{
572 con->capabilities= capabilities;
573}
574
576{
577 con->charset= charset;
578}
579
581{
582 con->status= status;
583}
584
586 uint32_t max_packet_size)
587{
588 con->max_packet_size= max_packet_size;
589}
590
605
607 drizzle_command_t *command, size_t *offset,
608 size_t *size, size_t *total,
609 drizzle_return_t *ret_ptr)
610{
611 if (drizzle_state_none(con))
612 {
613 con->packet_number= 0;
614 con->command_offset= 0;
615 con->command_total= 0;
616
619 }
620
621 *offset= con->command_offset;
622
623 *ret_ptr= drizzle_state_loop(con);
624 if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
625 *ret_ptr= DRIZZLE_RETURN_OK;
626
627 *command= con->command;
628 *size= con->command_size;
629 *total= con->command_total;
630
631 return con->command_data;
632}
633
635 drizzle_command_t *command, size_t *total,
636 drizzle_return_t *ret_ptr)
637{
638 uint8_t *command_data;
639 size_t offset= 0;
640 size_t size= 0;
641
642 command_data= drizzle_con_command_read(con, command, &offset, &size, total,
643 ret_ptr);
644 if (*ret_ptr != DRIZZLE_RETURN_OK)
645 return NULL;
646
647 if (command_data == NULL)
648 {
649 *total= 0;
650 return NULL;
651 }
652
653 if (con->command_buffer == NULL)
654 {
655 con->command_buffer= malloc((*total) + 1);
656 if (con->command_buffer == NULL)
657 {
658 drizzle_set_error(con->drizzle, "drizzle_command_buffer", "malloc");
659 *ret_ptr= DRIZZLE_RETURN_MEMORY;
660 return NULL;
661 }
662 }
663
664 memcpy(con->command_buffer + offset, command_data, size);
665
666 while ((offset + size) != (*total))
667 {
668 command_data= drizzle_con_command_read(con, command, &offset, &size, total,
669 ret_ptr);
670 if (*ret_ptr != DRIZZLE_RETURN_OK)
671 return NULL;
672
673 memcpy(con->command_buffer + offset, command_data, size);
674 }
675
676 command_data= con->command_buffer;
677 con->command_buffer= NULL;
678 command_data[*total]= 0;
679
680 return command_data;
681}
682
683/*
684 * Local Definitions
685 */
686
688{
689 switch (con->socket_type)
690 {
692 if (con->socket.tcp.addrinfo != NULL)
693 {
694 freeaddrinfo(con->socket.tcp.addrinfo);
695 con->socket.tcp.addrinfo= NULL;
696 }
697 break;
698
700 con->socket.uds.addrinfo.ai_addr= NULL;
701 break;
702
703 default:
704 break;
705 }
706
707 con->addrinfo_next= NULL;
708}
709
710/*
711 * State Definitions
712 */
713
715{
717 const char *host;
718 char port[NI_MAXSERV];
719 struct addrinfo ai;
720 int ret;
721
722 drizzle_log_debug(con->drizzle, "drizzle_state_addrinfo");
723
724 switch (con->socket_type)
725 {
727 tcp= &(con->socket.tcp);
728
729 if (tcp->addrinfo != NULL)
730 {
731 freeaddrinfo(tcp->addrinfo);
732 tcp->addrinfo= NULL;
733 }
734
735 if (tcp->port != 0)
736 snprintf(port, NI_MAXSERV, "%u", tcp->port);
737 else if (con->options & DRIZZLE_CON_MYSQL)
738 snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT_MYSQL);
739 else
740 snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT);
741
742 memset(&ai, 0, sizeof(struct addrinfo));
743 ai.ai_socktype= SOCK_STREAM;
744 ai.ai_protocol= IPPROTO_TCP;
745
746 if (con->options & DRIZZLE_CON_LISTEN)
747 {
748 ai.ai_flags = AI_PASSIVE;
749 ai.ai_family = AF_UNSPEC;
750 host= tcp->host;
751 }
752 else
753 {
754 if (tcp->host == NULL)
756 else
757 host= tcp->host;
758 }
759
760 ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
761 if (ret != 0)
762 {
763 drizzle_set_error(con->drizzle, "drizzle_state_addrinfo",
764 "getaddrinfo:%s", gai_strerror(ret));
766 }
767
768 con->addrinfo_next= tcp->addrinfo;
769
770 break;
771
773 con->addrinfo_next= &(con->socket.uds.addrinfo);
774 break;
775
776 default:
777 break;
778 }
779
781 return DRIZZLE_RETURN_OK;
782}
783
785{
786 int ret;
787 drizzle_return_t dret;
788
789 drizzle_log_debug(con->drizzle, "drizzle_state_connect");
790
791 if (con->fd != -1)
792 {
793 (void)close(con->fd);
794 con->fd= -1;
795 }
796
797 if (con->addrinfo_next == NULL)
798 {
799 drizzle_set_error(con->drizzle, "drizzle_state_connect",
800 "could not connect");
803 }
804
805 con->fd= socket(con->addrinfo_next->ai_family,
806 con->addrinfo_next->ai_socktype,
807 con->addrinfo_next->ai_protocol);
808 if (con->fd == -1)
809 {
810 drizzle_set_error(con->drizzle, "drizzle_state_connect", "socket:%d",
811 errno);
812 con->drizzle->last_errno= errno;
814 }
815
816 dret= _con_setsockopt(con);
817 if (dret != DRIZZLE_RETURN_OK)
818 {
819 con->drizzle->last_errno= errno;
820 return dret;
821 }
822
823 while (1)
824 {
825 ret= connect(con->fd, con->addrinfo_next->ai_addr,
826 con->addrinfo_next->ai_addrlen);
827
828 drizzle_log_crazy(con->drizzle, "connect return=%d errno=%d", ret, errno);
829
830 if (ret == 0)
831 {
832 con->addrinfo_next= NULL;
833 break;
834 }
835
836 if (errno == EAGAIN || errno == EINTR)
837 continue;
838
839 if (errno == EINPROGRESS)
840 {
843 return DRIZZLE_RETURN_OK;
844 }
845
846 if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == ETIMEDOUT)
847 {
848 con->addrinfo_next= con->addrinfo_next->ai_next;
849 return DRIZZLE_RETURN_OK;
850 }
851
852 drizzle_set_error(con->drizzle, "drizzle_state_connect", "connect:%d",
853 errno);
854 con->drizzle->last_errno= errno;
856 }
857
859 return DRIZZLE_RETURN_OK;
860}
861
863{
865
866 drizzle_log_debug(con->drizzle, "drizzle_state_connecting");
867
868 while (1)
869 {
870 if (con->revents & POLLOUT)
871 {
873 return DRIZZLE_RETURN_OK;
874 }
875 else if (con->revents & (POLLERR | POLLHUP | POLLNVAL))
876 {
877 con->revents= 0;
880 con->addrinfo_next= con->addrinfo_next->ai_next;
881 return DRIZZLE_RETURN_OK;
882 }
883
884 ret= drizzle_con_set_events(con, POLLOUT);
885 if (ret != DRIZZLE_RETURN_OK)
886 return ret;
887
890
891 ret= drizzle_con_wait(con->drizzle);
892 if (ret != DRIZZLE_RETURN_OK)
893 return ret;
894 }
895}
896
898{
900 ssize_t read_size;
901
902 drizzle_log_debug(con->drizzle, "drizzle_state_read");
903
904 if (con->buffer_size == 0)
905 con->buffer_ptr= con->buffer;
906 else if ((con->buffer_ptr - con->buffer) > (DRIZZLE_MAX_BUFFER_SIZE / 2))
907 {
908 memmove(con->buffer, con->buffer_ptr, con->buffer_size);
909 con->buffer_ptr= con->buffer;
910 }
911
912 while (1)
913 {
914 read_size= read(con->fd, con->buffer_ptr + con->buffer_size,
916 ((size_t)(con->buffer_ptr - con->buffer) +
917 con->buffer_size));
918
919 drizzle_log_crazy(con->drizzle, "read fd=%d return=%zd errno=%d", con->fd,
920 read_size, errno);
921
922 if (read_size == 0)
923 {
924 drizzle_set_error(con->drizzle, "drizzle_state_read",
925 "lost connection to server (EOF)");
927 }
928 else if (read_size == -1)
929 {
930 if (errno == EAGAIN)
931 {
932 ret= drizzle_con_set_events(con, POLLIN);
933 if (ret != DRIZZLE_RETURN_OK)
934 return 0;
935
938
939 ret= drizzle_con_wait(con->drizzle);
940 if (ret != DRIZZLE_RETURN_OK)
941 return ret;
942
943 continue;
944 }
945 else if (errno == ECONNREFUSED)
946 {
947 con->revents= 0;
950 con->addrinfo_next= con->addrinfo_next->ai_next;
951 return DRIZZLE_RETURN_OK;
952 }
953 else if (errno == EINTR)
954 continue;
955 else if (errno == EPIPE || errno == ECONNRESET)
956 {
957 drizzle_set_error(con->drizzle, "drizzle_state_read",
958 "lost connection to server (%d)", errno);
960 }
961
962 drizzle_set_error(con->drizzle, "drizzle_state_read", "read:%d", errno);
963 con->drizzle->last_errno= errno;
965 }
966
967 con->buffer_size+= (size_t)read_size;
968 break;
969 }
970
971 drizzle_state_pop(con);;
972 return DRIZZLE_RETURN_OK;
973}
974
976{
978 ssize_t write_size;
979
980 drizzle_log_debug(con->drizzle, "drizzle_state_write");
981
982 while (con->buffer_size != 0)
983 {
984 write_size= write(con->fd, con->buffer_ptr, con->buffer_size);
985
986 drizzle_log_crazy(con->drizzle, "write fd=%d return=%zd errno=%d", con->fd,
987 write_size, errno);
988
989 if (write_size == 0)
990 {
991 drizzle_set_error(con->drizzle, "drizzle_state_write",
992 "lost connection to server (EOF)");
994 }
995 else if (write_size == -1)
996 {
997 if (errno == EAGAIN)
998 {
999 ret= drizzle_con_set_events(con, POLLOUT);
1000 if (ret != DRIZZLE_RETURN_OK)
1001 return ret;
1002
1005
1006 ret= drizzle_con_wait(con->drizzle);
1007 if (ret != DRIZZLE_RETURN_OK)
1008 return ret;
1009
1010 continue;
1011 }
1012 else if (errno == EINTR)
1013 continue;
1014 else if (errno == EPIPE || errno == ECONNRESET)
1015 {
1016 drizzle_set_error(con->drizzle, "drizzle_state_write",
1017 "lost connection to server (%d)", errno);
1019 }
1020
1021 drizzle_set_error(con->drizzle, "drizzle_state_write", "write:%d", errno);
1022 con->drizzle->last_errno= errno;
1023 return DRIZZLE_RETURN_ERRNO;
1024 }
1025
1026 con->buffer_ptr+= write_size;
1027 con->buffer_size-= (size_t)write_size;
1028 if (con->buffer_size == 0)
1029 break;
1030 }
1031
1032 con->buffer_ptr= con->buffer;
1033
1034 drizzle_state_pop(con);
1035 return DRIZZLE_RETURN_OK;
1036}
1037
1039{
1040 char host[NI_MAXHOST];
1041 char port[NI_MAXSERV];
1042 int ret;
1043 int fd;
1044 int opt;
1045 drizzle_con_st *new_con;
1046
1047 for (; con->addrinfo_next != NULL;
1048 con->addrinfo_next= con->addrinfo_next->ai_next)
1049 {
1050 ret= getnameinfo(con->addrinfo_next->ai_addr,
1051 con->addrinfo_next->ai_addrlen, host, NI_MAXHOST, port,
1052 NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
1053 if (ret != 0)
1054 {
1055 drizzle_set_error(con->drizzle, "drizzle_state_listen", "getnameinfo:%s",
1056 gai_strerror(ret));
1058 }
1059
1060 /* Call to socket() can fail for some getaddrinfo results, try another. */
1061 fd= socket(con->addrinfo_next->ai_family, con->addrinfo_next->ai_socktype,
1062 con->addrinfo_next->ai_protocol);
1063 if (fd == -1)
1064 {
1065 drizzle_log_info(con->drizzle, "could not listen on %s:%s", host, port);
1066 drizzle_set_error(con->drizzle, "drizzle_state_listen", "socket:%d",
1067 errno);
1068 continue;
1069 }
1070
1071 opt= 1;
1072 ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1073 if (ret == -1)
1074 {
1075 close(fd);
1076 drizzle_set_error(con->drizzle, "drizzle_state_listen", "setsockopt:%d",
1077 errno);
1078 return DRIZZLE_RETURN_ERRNO;
1079 }
1080
1081 ret= bind(fd, con->addrinfo_next->ai_addr, con->addrinfo_next->ai_addrlen);
1082 if (ret == -1)
1083 {
1084 close(fd);
1085 drizzle_set_error(con->drizzle, "drizzle_state_listen", "bind:%d", errno);
1086 if (errno == EADDRINUSE)
1087 {
1088 if (con->fd == -1)
1089 {
1090 drizzle_log_info(con->drizzle, "could not listen on %s:%s", host,
1091 port);
1092 }
1093
1094 continue;
1095 }
1096
1097 return DRIZZLE_RETURN_ERRNO;
1098 }
1099
1100 if (listen(fd, con->backlog) == -1)
1101 {
1102 close(fd);
1103 drizzle_set_error(con->drizzle, "drizzle_state_listen", "listen:%d",
1104 errno);
1105 return DRIZZLE_RETURN_ERRNO;
1106 }
1107
1108 if (con->fd == -1)
1109 {
1110 con->fd= fd;
1111 new_con= con;
1112 }
1113 else
1114 {
1115 new_con= drizzle_con_clone(con->drizzle, NULL, con);
1116 if (new_con == NULL)
1117 {
1118 close(fd);
1119 return DRIZZLE_RETURN_MEMORY;
1120 }
1121
1122 new_con->fd= fd;
1123 }
1124
1125 /* Wait for read events on the listening socket. */
1126 ret= drizzle_con_set_events(new_con, POLLIN);
1127 if (ret != DRIZZLE_RETURN_OK)
1128 {
1129 drizzle_con_free(new_con);
1130 return ret;
1131 }
1132
1133 drizzle_log_info(con->drizzle, "listening on %s:%s", host, port);
1134 }
1135
1136 /* Report last socket() error if we couldn't find an address to bind. */
1137 if (con->fd == -1)
1138 return DRIZZLE_RETURN_ERRNO;
1139
1140 drizzle_state_pop(con);
1141 return DRIZZLE_RETURN_OK;
1142}
1143
1144/*
1145 * Static Definitions
1146 */
1147
1149{
1150 int ret;
1151 struct linger linger;
1152 struct timeval waittime;
1153
1154 ret= 1;
1155 ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, &ret,
1156 (socklen_t)sizeof(int));
1157 if (ret == -1 && errno != EOPNOTSUPP)
1158 {
1159 drizzle_set_error(con->drizzle, "_con_setsockopt",
1160 "setsockopt:TCP_NODELAY:%d", errno);
1161 return DRIZZLE_RETURN_ERRNO;
1162 }
1163
1164 linger.l_onoff= 1;
1165 linger.l_linger= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1166 ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, &linger,
1167 (socklen_t)sizeof(struct linger));
1168 if (ret == -1)
1169 {
1170 drizzle_set_error(con->drizzle, "_con_setsockopt",
1171 "setsockopt:SO_LINGER:%d", errno);
1172 return DRIZZLE_RETURN_ERRNO;
1173 }
1174
1175 waittime.tv_sec= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1176 waittime.tv_usec= 0;
1177 ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, &waittime,
1178 (socklen_t)sizeof(struct timeval));
1179 if (ret == -1 && errno != ENOPROTOOPT)
1180 {
1181 drizzle_set_error(con->drizzle, "_con_setsockopt",
1182 "setsockopt:SO_SNDTIMEO:%d", errno);
1183 return DRIZZLE_RETURN_ERRNO;
1184 }
1185
1186 ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, &waittime,
1187 (socklen_t)sizeof(struct timeval));
1188 if (ret == -1 && errno != ENOPROTOOPT)
1189 {
1190 drizzle_set_error(con->drizzle, "_con_setsockopt",
1191 "setsockopt:SO_RCVTIMEO:%d", errno);
1192 return DRIZZLE_RETURN_ERRNO;
1193 }
1194
1196 ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, &ret, (socklen_t)sizeof(int));
1197 if (ret == -1)
1198 {
1199 drizzle_set_error(con->drizzle, "_con_setsockopt",
1200 "setsockopt:SO_SNDBUF:%d", errno);
1201 return DRIZZLE_RETURN_ERRNO;
1202 }
1203
1205 ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, &ret, (socklen_t)sizeof(int));
1206 if (ret == -1)
1207 {
1208 drizzle_set_error(con->drizzle, "_con_setsockopt",
1209 "setsockopt:SO_RCVBUF:%d", errno);
1210 return DRIZZLE_RETURN_ERRNO;
1211 }
1212
1213 ret= fcntl(con->fd, F_GETFL, 0);
1214 if (ret == -1)
1215 {
1216 drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_GETFL:%d",
1217 errno);
1218 return DRIZZLE_RETURN_ERRNO;
1219 }
1220
1221 ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
1222 if (ret == -1)
1223 {
1224 drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_SETFL:%d",
1225 errno);
1226 return DRIZZLE_RETURN_ERRNO;
1227 }
1228
1229 return DRIZZLE_RETURN_OK;
1230}
System Include Files.
drizzle_command_t
Definition constants.h:214
@ DRIZZLE_COMMAND_QUIT
Definition constants.h:216
@ DRIZZLE_COMMAND_SHUTDOWN
Definition constants.h:223
@ DRIZZLE_COMMAND_PING
Definition constants.h:229
@ DRIZZLE_COMMAND_INIT_DB
Definition constants.h:217
drizzle_result_st * drizzle_con_shutdown(drizzle_con_st *con, drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition conn.c:405
drizzle_result_st * drizzle_select_db(drizzle_con_st *con, drizzle_result_st *result, const char *db, drizzle_return_t *ret_ptr)
Definition conn.c:397
drizzle_result_st * drizzle_shutdown(drizzle_con_st *con, drizzle_result_st *result, uint32_t level, drizzle_return_t *ret_ptr)
Definition conn.c:419
drizzle_return_t drizzle_con_connect(drizzle_con_st *con)
Definition conn.c:352
drizzle_result_st * drizzle_ping(drizzle_con_st *con, drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition conn.c:435
drizzle_result_st * drizzle_con_select_db(drizzle_con_st *con, drizzle_result_st *result, const char *db, drizzle_return_t *ret_ptr)
Definition conn.c:387
drizzle_result_st * drizzle_con_quit(drizzle_con_st *con, drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition conn.c:372
drizzle_result_st * drizzle_quit(drizzle_con_st *con, drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition conn.c:380
drizzle_result_st * drizzle_con_ping(drizzle_con_st *con, drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition conn.c:427
drizzle_result_st * drizzle_con_command_write(drizzle_con_st *con, drizzle_result_st *result, drizzle_command_t command, const void *data, size_t size, size_t total, drizzle_return_t *ret_ptr)
Definition conn.c:442
void drizzle_con_reset_addrinfo(drizzle_con_st *con)
Definition conn.c:687
static void drizzle_state_reset(drizzle_con_st *con)
Definition conn_local.h:84
static void drizzle_state_pop(drizzle_con_st *con)
Definition conn_local.h:73
static void drizzle_state_push(drizzle_con_st *con, drizzle_state_fn *function)
Definition conn_local.h:57
static bool drizzle_state_none(drizzle_con_st *con)
Definition conn_local.h:45
void drizzle_con_copy_handshake(drizzle_con_st *con, drizzle_con_st *from)
Definition conn.c:591
void drizzle_con_set_status(drizzle_con_st *con, drizzle_con_status_t status)
Definition conn.c:580
void drizzle_con_set_server_version(drizzle_con_st *con, const char *server_version)
Definition conn.c:540
int drizzle_con_backlog(const drizzle_con_st *con)
Definition conn.c:524
void drizzle_con_set_scramble(drizzle_con_st *con, const uint8_t *scramble)
Definition conn.c:558
drizzle_return_t drizzle_con_listen(drizzle_con_st *con)
Definition conn.c:510
void drizzle_con_set_max_packet_size(drizzle_con_st *con, uint32_t max_packet_size)
Definition conn.c:585
void drizzle_con_set_capabilities(drizzle_con_st *con, drizzle_capabilities_t capabilities)
Definition conn.c:569
void drizzle_con_set_charset(drizzle_con_st *con, drizzle_charset_t charset)
Definition conn.c:575
void * drizzle_con_command_read(drizzle_con_st *con, drizzle_command_t *command, size_t *offset, size_t *size, size_t *total, drizzle_return_t *ret_ptr)
Definition conn.c:606
void * drizzle_con_command_buffer(drizzle_con_st *con, drizzle_command_t *command, size_t *total, drizzle_return_t *ret_ptr)
Definition conn.c:634
void drizzle_con_set_thread_id(drizzle_con_st *con, uint32_t thread_id)
Definition conn.c:553
void drizzle_con_set_backlog(drizzle_con_st *con, int backlog)
Definition conn.c:529
void drizzle_con_set_protocol_version(drizzle_con_st *con, uint8_t protocol_version)
Definition conn.c:534
static drizzle_return_t _con_setsockopt(drizzle_con_st *con)
Definition conn.c:1148
void drizzle_con_set_options(drizzle_con_st *con, drizzle_con_options_t options)
Definition conn.c:158
drizzle_con_options_t drizzle_con_options(const drizzle_con_st *con)
Definition conn.c:153
in_port_t drizzle_con_port(const drizzle_con_st *con)
Definition conn.c:193
void drizzle_con_remove_options(drizzle_con_st *con, drizzle_con_options_t options)
Definition conn.c:174
int drizzle_con_errno(const drizzle_con_st *con)
Definition conn.c:138
const uint8_t * drizzle_con_scramble(const drizzle_con_st *con)
Definition conn.c:323
uint8_t drizzle_con_protocol_version(const drizzle_con_st *con)
Definition conn.c:289
const char * drizzle_con_password(const drizzle_con_st *con)
Definition conn.c:232
drizzle_st * drizzle_con_drizzle(const drizzle_con_st *con)
Definition conn.c:128
void drizzle_con_set_context(drizzle_con_st *con, void *context)
Definition conn.c:278
uint32_t drizzle_con_server_version_number(const drizzle_con_st *con)
Definition conn.c:299
uint32_t drizzle_con_max_packet_size(const drizzle_con_st *con)
Definition conn.c:343
uint32_t drizzle_con_thread_id(const drizzle_con_st *con)
Definition conn.c:318
void drizzle_con_set_db(drizzle_con_st *con, const char *db)
Definition conn.c:262
const char * drizzle_con_sqlstate(const drizzle_con_st *con)
Definition conn.c:148
drizzle_capabilities_t drizzle_con_capabilities(const drizzle_con_st *con)
Definition conn.c:328
drizzle_return_t drizzle_con_set_events(drizzle_con_st *con, short events)
Definition conn.c:75
int drizzle_con_fd(const drizzle_con_st *con)
Definition conn.c:39
uint16_t drizzle_con_error_code(const drizzle_con_st *con)
Definition conn.c:143
void * drizzle_con_context(const drizzle_con_st *con)
Definition conn.c:273
drizzle_con_status_t
Definition constants.h:160
drizzle_return_t drizzle_con_set_revents(drizzle_con_st *con, short revents)
Definition conn.c:98
drizzle_capabilities_t
Definition constants.h:179
drizzle_return_t drizzle_con_set_fd(drizzle_con_st *con, int fd)
Definition conn.c:44
void drizzle_con_set_tcp(drizzle_con_st *con, const char *host, in_port_t port)
Definition conn.c:209
const char * drizzle_con_error(const drizzle_con_st *con)
Definition conn.c:133
drizzle_charset_t drizzle_con_charset(const drizzle_con_st *con)
Definition conn.c:333
void drizzle_con_close(drizzle_con_st *con)
Definition conn.c:57
const char * drizzle_con_db(const drizzle_con_st *con)
Definition conn.c:257
const char * drizzle_con_user(const drizzle_con_st *con)
Definition conn.c:227
const char * drizzle_con_host(const drizzle_con_st *con)
Definition conn.c:180
drizzle_con_status_t drizzle_con_status(const drizzle_con_st *con)
Definition conn.c:338
void drizzle_con_set_auth(drizzle_con_st *con, const char *user, const char *password)
Definition conn.c:237
void drizzle_con_add_options(drizzle_con_st *con, drizzle_con_options_t options)
Definition conn.c:164
const char * drizzle_con_server_version(const drizzle_con_st *con)
Definition conn.c:294
void drizzle_con_set_context_free_fn(drizzle_con_st *con, drizzle_con_context_free_fn *function)
Definition conn.c:283
drizzle_con_options_t
Definition constants.h:132
@ DRIZZLE_CON_SOCKET_TCP
Definition constants.h:151
@ DRIZZLE_CON_SOCKET_UDS
Definition constants.h:152
@ DRIZZLE_CON_NO_RESULT_READ
Definition constants.h:139
@ DRIZZLE_CON_LISTEN
Definition constants.h:141
@ DRIZZLE_CON_IO_READY
Definition constants.h:140
@ DRIZZLE_CON_EXPERIMENTAL
Definition constants.h:142
@ DRIZZLE_CON_MYSQL
Definition constants.h:135
@ DRIZZLE_CON_READY
Definition constants.h:138
@ DRIZZLE_CON_RAW_PACKET
Definition constants.h:136
#define DRIZZLE_MAX_USER_SIZE
Definition constants.h:45
#define DRIZZLE_MAX_BUFFER_SIZE
Definition constants.h:55
#define DRIZZLE_DEFAULT_TCP_PORT
Definition constants.h:39
#define DRIZZLE_DEFAULT_TCP_PORT_MYSQL
Definition constants.h:40
#define DRIZZLE_MAX_PASSWORD_SIZE
Definition constants.h:46
#define DRIZZLE_DEFAULT_SOCKET_SEND_SIZE
Definition constants.h:62
#define DRIZZLE_MAX_SCRAMBLE_SIZE
Definition constants.h:58
drizzle_return_t
Definition constants.h:69
#define DRIZZLE_MAX_DB_SIZE
Definition constants.h:47
#define DRIZZLE_DEFAULT_SOCKET_TIMEOUT
Definition constants.h:61
#define DRIZZLE_MAX_SERVER_VERSION_SIZE
Definition constants.h:57
#define DRIZZLE_DEFAULT_SOCKET_RECV_SIZE
Definition constants.h:63
#define DRIZZLE_DEFAULT_TCP_HOST
Definition constants.h:38
@ DRIZZLE_RETURN_ERROR_CODE
Definition constants.h:87
@ DRIZZLE_RETURN_PAUSE
Definition constants.h:72
@ DRIZZLE_RETURN_OK
Definition constants.h:70
@ DRIZZLE_RETURN_IO_WAIT
Definition constants.h:71
@ DRIZZLE_RETURN_LOST_CONNECTION
Definition constants.h:90
@ DRIZZLE_RETURN_ERRNO
Definition constants.h:75
@ DRIZZLE_RETURN_COULD_NOT_CONNECT
Definition constants.h:91
@ DRIZZLE_RETURN_NOT_READY
Definition constants.h:78
@ DRIZZLE_RETURN_GETADDRINFO
Definition constants.h:77
@ DRIZZLE_RETURN_MEMORY
Definition constants.h:74
static void drizzle_log_debug(drizzle_st *drizzle, const char *format,...)
static void drizzle_log_crazy(drizzle_st *drizzle, const char *format,...)
void drizzle_set_error(drizzle_st *drizzle, const char *function, const char *format,...)
Definition drizzle.c:633
static void drizzle_log_info(drizzle_st *drizzle, const char *format,...)
drizzle_result_st * drizzle_result_create(drizzle_con_st *con, drizzle_result_st *result)
Definition result.c:22
void drizzle_result_free(drizzle_result_st *result)
Definition result.c:75
drizzle_return_t drizzle_state_packet_read(drizzle_con_st *con)
Definition state.c:40
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
Definition conn.c:975
drizzle_return_t drizzle_state_addrinfo(drizzle_con_st *con)
Definition conn.c:714
drizzle_return_t drizzle_state_command_read(drizzle_con_st *con)
Definition command.c:61
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
Definition conn.c:897
drizzle_return_t drizzle_state_connecting(drizzle_con_st *con)
Definition conn.c:862
drizzle_return_t drizzle_state_command_write(drizzle_con_st *con)
Definition command.c:103
drizzle_return_t drizzle_state_handshake_server_read(drizzle_con_st *con)
Definition handshake.c:74
drizzle_return_t drizzle_state_listen(drizzle_con_st *con)
Definition conn.c:1038
drizzle_return_t drizzle_state_connect(drizzle_con_st *con)
Definition conn.c:784
drizzle_return_t drizzle_state_loop(drizzle_con_st *con)
Definition state.c:18
void drizzle_con_context_free_fn(drizzle_con_st *con, void *context)
Definition constants.h:422
uint8_t drizzle_charset_t
Definition constants.h:414
drizzle_con_st * drizzle_con_clone(drizzle_st *drizzle, drizzle_con_st *con, const drizzle_con_st *from)
Definition drizzle.c:309
const char * drizzle_error(const drizzle_st *drizzle)
Definition drizzle.c:146
int drizzle_errno(const drizzle_st *drizzle)
Definition drizzle.c:151
const char * drizzle_sqlstate(const drizzle_st *drizzle)
Definition drizzle.c:161
uint16_t drizzle_error_code(const drizzle_st *drizzle)
Definition drizzle.c:156
drizzle_return_t drizzle_con_wait(drizzle_st *drizzle)
Definition drizzle.c:376
void drizzle_con_free(drizzle_con_st *con)
Definition drizzle.c:343
@ DRIZZLE_NON_BLOCKING
Definition constants.h:122
size_t command_offset
Definition structs.h:93
uint8_t packet_number
Definition structs.h:76
uint8_t buffer[DRIZZLE_MAX_BUFFER_SIZE]
Definition structs.h:115
drizzle_capabilities_t capabilities
Definition structs.h:81
drizzle_st * drizzle
Definition structs.h:103
drizzle_result_st * result
Definition structs.h:107
struct addrinfo * addrinfo_next
Definition structs.h:97
uint8_t * command_buffer
Definition structs.h:99
drizzle_charset_t charset
Definition structs.h:82
short events
Definition structs.h:79
uint8_t * command_data
Definition structs.h:100
uint32_t thread_id
Definition structs.h:89
drizzle_con_options_t options
Definition structs.h:84
union drizzle_con_st::@0 socket
drizzle_con_status_t status
Definition structs.h:86
uint8_t * scramble
Definition structs.h:109
char server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE]
Definition structs.h:119
size_t command_total
Definition structs.h:95
uint8_t * buffer_ptr
Definition structs.h:98
drizzle_con_context_free_fn * context_free_fn
Definition structs.h:102
drizzle_con_tcp_st tcp
Definition structs.h:112
void * context
Definition structs.h:101
size_t command_size
Definition structs.h:94
drizzle_con_socket_t socket_type
Definition structs.h:85
uint32_t max_packet_size
Definition structs.h:87
char db[DRIZZLE_MAX_DB_SIZE]
Definition structs.h:116
size_t buffer_size
Definition structs.h:92
drizzle_con_uds_st uds
Definition structs.h:113
uint8_t protocol_version
Definition structs.h:77
short revents
Definition structs.h:80
char password[DRIZZLE_MAX_PASSWORD_SIZE]
Definition structs.h:117
drizzle_command_t command
Definition structs.h:83
char user[DRIZZLE_MAX_USER_SIZE]
Definition structs.h:121
uint8_t scramble_buffer[DRIZZLE_MAX_SCRAMBLE_SIZE]
Definition structs.h:118
in_port_t port
Definition structs.h:56
char host_buffer[NI_MAXHOST]
Definition structs.h:59
struct addrinfo * addrinfo
Definition structs.h:57
struct addrinfo addrinfo
Definition structs.h:67
drizzle_options_t options
Definition structs.h:29
void * event_watch_context
Definition structs.h:42
drizzle_event_watch_fn * event_watch_fn
Definition structs.h:41
int last_errno
Definition structs.h:36