]>
Commit | Line | Data |
---|---|---|
ad02a0eb SH |
1 | /************************************************************************ |
2 | * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) | |
3 | * Copyright (C) 2001-2003 Optical Access | |
4 | * Author: Alex Rozin | |
5 | * | |
6 | * This file is part of RSTP library. | |
7 | * | |
8 | * RSTP library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU Lesser General Public License as published by the | |
10 | * Free Software Foundation; version 2.1 | |
11 | * | |
12 | * RSTP library is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with RSTP library; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | **********************************************************************/ | |
22 | ||
23 | #include <stdlib.h> | |
24 | #include <stdio.h> | |
25 | #include <string.h> | |
26 | #include <errno.h> | |
27 | #include <sys/time.h> | |
28 | #include <unistd.h> | |
29 | ||
30 | #include "uid_sock.h" | |
31 | ||
32 | static int Socket(int family, int type, int protocol) | |
33 | { | |
34 | int sock_fd; | |
35 | ||
36 | sock_fd = socket(family, type, protocol); | |
37 | ||
38 | if (sock_fd < 0) { | |
39 | return -1; | |
40 | } | |
41 | ||
42 | return sock_fd; | |
43 | } | |
44 | ||
45 | #define UID_SET_SOCKET_ID(SPTR, X) \ | |
46 | strncpy((SPTR)->socket_id, (X),SOCKET_NAME_LENGTH); \ | |
47 | (SPTR)->socket_id[SOCKET_NAME_LENGTH - 1] = '\0'; | |
48 | ||
49 | #define UID_SET_SOCKET_SERVER_ID(SPTR, X) \ | |
50 | (SPTR)->serverAddr.sun_path[0] = '\0'; \ | |
51 | strncpy((SPTR)->serverAddr.sun_path + 1, (X),SOCKET_NAME_LENGTH - 1); \ | |
52 | (SPTR)->serverAddr.sun_path[SOCKET_NAME_LENGTH - 1] = '\0'; | |
53 | ||
54 | #define UID_SET_SOCKET_CLIENT_ID(SPTR, X) \ | |
55 | (SPTR)->clientAddr.sun_path[0] = '\0'; \ | |
56 | strncpy((SPTR)->clientAddr.sun_path + 1, (X),SOCKET_NAME_LENGTH - 1); \ | |
57 | (SPTR)->clientAddr.sun_path[SOCKET_NAME_LENGTH - 1] = '\0'; | |
58 | ||
59 | int | |
60 | UiD_SocketCompare (UID_SOCKET_T* s, UID_SOCKET_T* t) | |
61 | { | |
62 | register char* ps; | |
63 | register char* pt; | |
64 | ||
65 | ps = s->clientAddr.sun_path; | |
66 | if (! *ps) ps++; | |
67 | if (! *ps) return 1; | |
68 | ||
69 | pt = t->clientAddr.sun_path; | |
70 | if (! *pt) pt++; | |
71 | if (! *pt) return 2; | |
72 | ||
73 | if (strcmp (pt, ps)) | |
74 | return 3; | |
75 | else { | |
76 | return 0; | |
77 | } | |
78 | } | |
79 | ||
80 | int UiD_SocketInit(UID_SOCKET_T* s, | |
81 | UID_SOCK_ID socket_id, | |
82 | TYPE_OF_BINDING binding) | |
83 | { | |
84 | bzero(s, sizeof (UID_SOCKET_T)); | |
85 | ||
86 | s->sock_fd = Socket(AF_LOCAL, SOCK_DGRAM, 0); | |
87 | ||
88 | s->clientAddr.sun_family = AF_LOCAL; | |
89 | ||
90 | s->serverAddr.sun_family = AF_LOCAL; | |
91 | ||
92 | ||
93 | switch (binding) { | |
94 | case UID_BIND_AS_CLIENT: | |
95 | strncpy (s->socket_id, tmpnam(NULL),SOCKET_NAME_LENGTH ); | |
96 | UID_SET_SOCKET_CLIENT_ID(s,s->socket_id ); | |
97 | if (bind(s->sock_fd, (SA *)&(s->clientAddr), SIZE_OF_ADDRESS) < 0) { | |
98 | return -2; | |
99 | } | |
100 | bzero(&s->serverAddr, SIZE_OF_ADDRESS); | |
101 | s->serverAddr.sun_family = AF_LOCAL; | |
102 | UID_SET_SOCKET_SERVER_ID(s, socket_id); | |
103 | ||
104 | break; | |
105 | ||
106 | case UID_BIND_AS_SERVER: | |
107 | unlink(socket_id); | |
108 | strncpy (s->socket_id, socket_id, SOCKET_NAME_LENGTH); | |
109 | UID_SET_SOCKET_SERVER_ID(s,s->socket_id); | |
110 | ||
111 | if (bind(s->sock_fd, (SA *)&(s->serverAddr), SIZE_OF_ADDRESS) < 0) { | |
112 | perror ("Error:"); | |
113 | fflush (stdout); | |
114 | return -4; | |
115 | } | |
116 | ||
117 | break; | |
118 | ||
119 | default: | |
120 | return -5; | |
121 | } | |
122 | ||
123 | s->binding = binding; | |
124 | ||
125 | return 0; | |
126 | } | |
127 | ||
128 | int UiD_SocketRecvfrom (UID_SOCKET_T* sock, | |
129 | void* msg, int buffer_size, | |
130 | UID_SOCKET_T* sock_4_reply) | |
131 | { | |
132 | int size; | |
133 | socklen_t len = SIZE_OF_ADDRESS; | |
134 | ||
135 | while (1) { | |
136 | size = recvfrom(sock->sock_fd, msg, buffer_size, 0, | |
137 | (struct sockaddr *)(((UID_BIND_AS_CLIENT == sock->binding) || !sock_4_reply) ? | |
138 | NULL : &(sock_4_reply->clientAddr)), | |
139 | (UID_BIND_AS_CLIENT == (sock->binding)) ? | |
140 | NULL : &len); | |
141 | if (size < 0 && errno == EINTR) continue; | |
142 | break; | |
143 | } | |
144 | ||
145 | if ((UID_BIND_AS_CLIENT != sock->binding) && sock_4_reply) { | |
146 | sock_4_reply->sock_fd = sock->sock_fd; | |
147 | sock_4_reply->binding = UID_BIND_AS_SERVER; | |
148 | } | |
149 | ||
150 | return size; | |
151 | } | |
152 | ||
153 | int UiD_SocketSendto (UID_SOCKET_T* sock, void* msg, int msg_size) | |
154 | { | |
155 | int rc, size = 0; | |
156 | ||
157 | while (size != msg_size) { | |
158 | rc = sendto (sock->sock_fd, (msg+size), (msg_size-size), 0, | |
159 | (struct sockaddr *)((UID_BIND_AS_CLIENT == sock->binding) ? &sock->serverAddr : &sock->clientAddr), | |
160 | SIZE_OF_ADDRESS); | |
161 | ||
162 | if (rc < 0) { | |
163 | if (errno == EINTR) { | |
164 | continue; | |
165 | } else { | |
166 | return -1; | |
167 | } | |
168 | } | |
169 | size += rc; | |
170 | } | |
171 | ||
172 | return 0; | |
173 | } | |
174 | ||
175 | int UiD_SocketClose(UID_SOCKET_T* s) | |
176 | { | |
177 | close (s->sock_fd); | |
178 | ||
179 | return 0; | |
180 | } | |
181 | ||
182 | int UiD_SocketSetReadTimeout (UID_SOCKET_T* s, int timeout) | |
183 | { | |
184 | int retval = -1; | |
185 | struct timeval wait; | |
186 | fd_set read_mask; | |
187 | ||
188 | wait.tv_sec = timeout; | |
189 | wait.tv_usec = 0; | |
190 | ||
191 | FD_ZERO(&read_mask); | |
192 | FD_SET(s->sock_fd, &read_mask); | |
193 | ||
194 | retval = select (s->sock_fd + 1, &read_mask, NULL, NULL, &wait); | |
195 | ||
196 | if (retval < 0) { // Error | |
197 | fprintf (stderr, "UiD_SocketSetReadTimeout failed: %s\n", strerror(errno)); | |
198 | return 0; | |
199 | } else if (! retval) { // Timeout expired | |
200 | return 0; | |
201 | } else { // 0 | |
202 | ; | |
203 | } | |
204 | ||
205 | return retval; | |
206 | } | |
207 | ||
208 |