00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef socket_info_h
00032 #define socket_info_h
00033
00034 #include <stdlib.h>
00035
00036 #include "ip_addr.h"
00037 #include "dprint.h"
00038 #include "globals.h"
00039 #include "ut.h"
00040
00041
00042 extern struct socket_info* udp_listen;
00043 #ifdef USE_TCP
00044 extern struct socket_info* tcp_listen;
00045 #endif
00046 #ifdef USE_TLS
00047 extern struct socket_info* tls_listen;
00048 #endif
00049 #ifdef USE_SCTP
00050 extern struct socket_info* sctp_listen;
00051 #endif
00052
00053
00054 int add_listen_iface(char* name, unsigned short port, unsigned short proto,
00055 enum si_flags flags);
00056 int fix_all_socket_lists(void);
00057 void print_all_socket_lists(void);
00058 void print_aliases(void);
00059
00060 struct socket_info* grep_sock_info(str* host, unsigned short port,
00061 unsigned short proto);
00062 struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
00063 unsigned short proto);
00064
00065
00066 static inline struct socket_info** get_sock_info_list(unsigned short proto)
00067 {
00068
00069 switch(proto){
00070 case PROTO_UDP:
00071 return &udp_listen;
00072 break;
00073 #ifdef USE_TCP
00074 case PROTO_TCP:
00075 return &tcp_listen;
00076 break;
00077 #endif
00078 #ifdef USE_TLS
00079 case PROTO_TLS:
00080 return &tls_listen;
00081 break;
00082 #endif
00083 #ifdef USE_SCTP
00084 case PROTO_SCTP:
00085 return &sctp_listen;
00086 break;
00087 #endif
00088 default:
00089 LM_CRIT("invalid proto %d\n", proto);
00090 }
00091 return 0;
00092 }
00093
00094
00095
00096
00097
00098 static inline int next_proto(unsigned short proto)
00099 {
00100 switch(proto){
00101 case PROTO_NONE:
00102 return PROTO_UDP;
00103 case PROTO_UDP:
00104 #ifdef USE_TCP
00105 if(!tcp_disable)
00106 return PROTO_TCP;
00107 #ifdef USE_SCTP
00108 return (sctp_disable)?0:PROTO_SCTP;
00109 #else
00110 return 0;
00111 #endif
00112 #else
00113 #ifdef USE_SCTP
00114 return (sctp_disable)?0:PROTO_SCTP;
00115 #else
00116 return 0;
00117 #endif
00118 #endif
00119 #ifdef USE_TCP
00120 case PROTO_TCP:
00121 #ifdef USE_TLS
00122 if (!tls_disable)
00123 return PROTO_TLS;
00124 #ifdef USE_SCTP
00125 return (sctp_disable)?0:PROTO_SCTP;
00126 #else
00127 return 0;
00128 #endif
00129 #else
00130 #ifdef USE_SCTP
00131 return (sctp_disable)?0:PROTO_SCTP;
00132 #else
00133 return 0;
00134 #endif
00135 #endif
00136 #endif
00137 #ifdef USE_TLS
00138 case PROTO_TLS:
00139 #ifdef USE_SCTP
00140 return (sctp_disable)?0:PROTO_SCTP;
00141 #else
00142 return 0;
00143 #endif
00144 #endif
00145 #ifdef USE_SCTP
00146 case PROTO_SCTP:
00147 return 0;
00148 #endif
00149 default:
00150 LM_ERR("unknown proto %d\n", proto);
00151 }
00152 return 0;
00153 }
00154
00155
00156
00157
00158
00159
00160 inline static struct socket_info* get_first_socket(void)
00161 {
00162 if (udp_listen) return udp_listen;
00163 #ifdef USE_TCP
00164 else if (tcp_listen) return tcp_listen;
00165 #ifdef USE_TLS
00166 else if (tls_listen) return tls_listen;
00167 #endif
00168 #endif
00169 #ifdef USE_SCTP
00170 else if (sctp_listen) return sctp_listen;
00171 #endif
00172 return 0;
00173 }
00174
00175
00176
00177
00178
00179 inline static int parse_proto(unsigned char* s, long len, int* proto)
00180 {
00181 #define PROTO2UINT(a, b, c) (( (((unsigned int)(a))<<16)+ \
00182 (((unsigned int)(b))<<8)+ \
00183 ((unsigned int)(c)) ) | 0x20202020)
00184 unsigned int i;
00185
00186
00187
00188 *proto=PROTO_NONE;
00189 if (len!=3 && len!=4) return -1;
00190
00191 i=PROTO2UINT(s[0], s[1], s[2]);
00192 switch(i){
00193 case PROTO2UINT('u', 'd', 'p'):
00194 if(len==3) { *proto=PROTO_UDP; return 0; }
00195 break;
00196 #ifdef USE_TCP
00197 case PROTO2UINT('t', 'c', 'p'):
00198 if(len==3) { *proto=PROTO_TCP; return 0; }
00199 break;
00200 #ifdef USE_TLS
00201 case PROTO2UINT('t', 'l', 's'):
00202 if(len==3) { *proto=PROTO_TLS; return 0; }
00203 break;
00204 #endif
00205 #endif
00206 #ifdef USE_SCTP
00207 case PROTO2UINT('s', 'c', 't'):
00208 if(len==4 && (s[3]=='p' || s[3]=='P')) {
00209 *proto=PROTO_SCTP; return 0;
00210 }
00211 break;
00212 #endif
00213
00214 default:
00215 return -1;
00216 }
00217 return -1;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 inline static int parse_phostport(char* s, int slen, char** host, int* hlen,
00227 int* port, int* proto)
00228 {
00229 char* first;
00230 char* second;
00231 char* p;
00232 int bracket;
00233 str tmp;
00234 char* end;
00235
00236 first=second=0;
00237 bracket=0;
00238 end = s + slen;
00239
00240
00241
00242
00243 for(p=s; p<end ; p++){
00244 switch(*p){
00245 case '[':
00246 bracket++;
00247 if (bracket>1) goto error_brackets;
00248 break;
00249 case ']':
00250 bracket--;
00251 if (bracket<0) goto error_brackets;
00252 break;
00253 case ':':
00254 if (bracket==0){
00255 if (first==0) first=p;
00256 else if( second==0) second=p;
00257 else goto error_colons;
00258 }
00259 break;
00260 }
00261 }
00262 if (p==s) return -1;
00263 if (*(p-1)==':') goto error_colons;
00264
00265 if (first==0){
00266 *host=s;
00267 *hlen=(int)(p-s);
00268 *port=0;
00269 *proto=0;
00270 return 0;
00271 }
00272 if (second){
00273 if (parse_proto((unsigned char*)s, first-s, proto)<0)
00274 goto error_proto;
00275 tmp.s = second+1;
00276 tmp.len = end - tmp.s;
00277 if (str2int( &tmp, (unsigned int*)port )==-1) goto error_port;
00278 *host=first+1;
00279 *hlen=(int)(second-*host);
00280 return 0;
00281 }
00282
00283 tmp.s = first+1;
00284 tmp.len = end - tmp.s;
00285 if (str2int( &tmp, (unsigned int*)port )==-1) {
00286
00287 if (parse_proto((unsigned char*)s, first-s, proto)<0) goto error_proto;
00288 *port=0;
00289 *host=first+1;
00290 *hlen=(int)(p-*host);
00291 }else{
00292
00293 *proto=0;
00294 *host=s;
00295 *hlen=(int)(first-*host);
00296 }
00297 return 0;
00298 error_brackets:
00299 LM_ERR("too many brackets in %s\n", s);
00300 return -1;
00301 error_colons:
00302 LM_ERR(" too many colons in %s\n", s);
00303 return -1;
00304 error_proto:
00305 LM_ERR("bad protocol in %s\n", s);
00306 return -1;
00307 error_port:
00308 LM_ERR("bad port number in %s\n", s);
00309 return -1;
00310 }
00311
00312
00313 #define MAX_SOCKET_STR ( 4 + 1 + IP_ADDR_MAX_STR_SIZE+1+INT2STR_MAX_LEN+1)
00314 #define sock_str_len(_sock) ( 3 + 1*((_sock)->proto==PROTO_SCTP) + 1 + \
00315 (_sock)->address_str.len + 1 + (_sock)->port_no_str.len)
00316
00317 static inline char* socket2str(struct socket_info *sock, char *s, int* len)
00318 {
00319 static char buf[MAX_SOCKET_STR];
00320 char *p,*p1;
00321
00322 if (s) {
00323
00324 if ( sock_str_len(sock) > *len ) {
00325 LM_ERR("buffer too short\n");
00326 return 0;
00327 }
00328 p = p1 = s;
00329 } else {
00330 p = p1 = buf;
00331 }
00332
00333 switch (sock->proto) {
00334 case PROTO_UDP:
00335 *(p++) = 'u';
00336 *(p++) = 'd';
00337 *(p++) = 'p';
00338 break;
00339 case PROTO_TCP:
00340 *(p++) = 't';
00341 *(p++) = 'c';
00342 *(p++) = 'p';
00343 break;
00344 case PROTO_TLS:
00345 *(p++) = 't';
00346 *(p++) = 'l';
00347 *(p++) = 's';
00348 break;
00349 case PROTO_SCTP:
00350 *(p++) = 's';
00351 *(p++) = 'c';
00352 *(p++) = 't';
00353 *(p++) = 'p';
00354 break;
00355 default:
00356 LM_CRIT("unsupported proto %d\n", sock->proto);
00357 return 0;
00358 }
00359 *(p++) = ':';
00360 memcpy( p, sock->address_str.s, sock->address_str.len);
00361 p += sock->address_str.len;
00362 *(p++) = ':';
00363 memcpy( p, sock->port_no_str.s, sock->port_no_str.len);
00364 p += sock->port_no_str.len;
00365 *len = (int)(long)(p-p1);
00366 LM_DBG("<%.*s>\n",*len,p1);
00367 return p1;
00368 }
00369
00370
00371
00372 #endif