core: Changed WS from being a flag on a TCP/TLS connection to a protocol in its own...
[sip-router] / ip_addr.h
index 7f9b8e0..115e4b4 100644 (file)
--- a/ip_addr.h
+++ b/ip_addr.h
@@ -34,6 +34,7 @@
  *  2006-04-21  added init_dst_from_rcv (andrei)
  *  2007-06-26  added ip_addr_mk_any() (andrei)
  *  2008-05-21  added su2a(), ip_addr2sbuf(), ip4tosbuf(), ip62sbuf() (andrei)
+ *  2009-09-14  added send flags support to dest_info (andrei)
  */
 
 #ifndef ip_addr_h
@@ -51,8 +52,8 @@
 
 #include "dprint.h"
 
-enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
-#define PROTO_LAST PROTO_SCTP
+enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP, PROTO_WS, PROTO_WSS, PROTO_OTHER };
+#define PROTO_LAST PROTO_OTHER
 
 #ifdef USE_COMP
 enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
@@ -71,7 +72,7 @@ struct ip_addr{
        }u;
 };
 
-
+typedef struct ip_addr ip_addr_t;
 
 struct net{
        struct ip_addr ip;
@@ -89,13 +90,32 @@ union sockaddr_union{
 
 
 enum si_flags { SI_NONE=0, SI_IS_IP=1, SI_IS_LO=2, SI_IS_MCAST=4,
-                                SI_IS_ANY=8 };
+                                SI_IS_ANY=8, SI_IS_MHOMED=16 };
+
+struct addr_info{
+       str name; /* name - eg.: foo.bar or 10.0.0.1 */
+       struct ip_addr address; /*ip address */
+       str address_str;        /*ip address converted to string -- optimization*/
+       enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
+       union sockaddr_union su;
+       struct addr_info* next;
+       struct addr_info* prev;
+};
+
+struct advertise_info {
+       str name; /* name - eg.: foo.bar or 10.0.0.1 */
+       unsigned short port_no;  /* port number */
+       str port_no_str; /* port number converted to string -- optimization*/
+       str address_str;        /*ip address converted to string -- optimization*/
+       struct ip_addr address; /* ip address */
+       str sock_str; /* Socket proto, ip, and port as string */
+};
 
 struct socket_info{
        int socket;
        str name; /* name - eg.: foo.bar or 10.0.0.1 */
        struct ip_addr address; /* ip address */
-       str address_str;        /* ip address converted to string -- optimization*/
+       str address_str;        /*ip address converted to string -- optimization*/
        str port_no_str; /* port number converted to string -- optimization*/
        enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
        union sockaddr_union su; 
@@ -103,6 +123,11 @@ struct socket_info{
        struct socket_info* prev;
        unsigned short port_no;  /* port number */
        char proto; /* tcp or udp*/
+       str sock_str; /* Socket proto, ip, and port as string */
+       struct addr_info* addr_info_lst; /* extra addresses (e.g. SCTP mh) */
+       int workers; /* number of worker processes for this socket */
+       int workers_tcpidx; /* index of workers in tcp children array */
+       struct advertise_info useinfo; /* details to be used in SIP msg */
 };
 
 
@@ -124,19 +149,63 @@ struct receive_info{
 };
 
 
+/* send flags */
+#define SND_F_FORCE_CON_REUSE  1 /* reuse an existing connection or fail */
+#define SND_F_CON_CLOSE                        2 /* close the connection after sending */
+#define SND_F_FORCE_SOCKET             4 /* send socket in dst is forced */
+
+struct snd_flags {
+       unsigned char f;          /* snd flags */
+       unsigned char blst_imask; /* blacklist ignore mask */
+};
+
+
+typedef struct snd_flags  snd_flags_t;
+
+#define SND_FLAGS_INIT(sflags) \
+       do{ \
+               (sflags)->f=0; \
+               (sflags)->blst_imask=0; \
+       }while(0)
+
+#define SND_FLAGS_OR(dst, src1, src2) \
+       do{ \
+               (dst)->f = (src1)->f | (src2)->f; \
+               (dst)->blst_imask = (src1)->blst_imask | (src2)->blst_imask; \
+       }while(0)
+
+#define SND_FLAGS_AND(dst, src1, src2) \
+       do{ \
+               (dst)->f = (src1)->f & (src2)->f; \
+               (dst)->blst_imask = (src1)->blst_imask & (src2)->blst_imask; \
+       }while(0)
+
 struct dest_info{
        struct socket_info* send_sock;
        union sockaddr_union to;
        int id; /* tcp stores the connection id here */ 
        char proto;
+       snd_flags_t send_flags;
 #ifdef USE_COMP
        short comp;
 #endif
 };
 
 
-struct socket_id{
+/* list of names for multi-homed sockets that need to bind on
+ * multiple addresses in the same time (sctp ) */
+struct name_lst{
        char* name;
+       struct name_lst* next;
+       int flags;
+};
+
+
+struct socket_id{
+       struct name_lst* addr_lst; /* address list, the first one must
+                                                                 be present and is the main one
+                                                                 (in case of multihoming sctp)*/
+       int flags;
        int proto;
        int port;
        struct socket_id* next;
@@ -183,13 +252,21 @@ struct socket_id{
 
 
 
-struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask);
-struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
+struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask);
+struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
+int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask);
+int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen);
+int mk_net_str(struct net* dst, str* s);
 
 void print_ip(char* prefix, struct ip_addr* ip, char* suffix);
 void stdout_print_ip(struct ip_addr* ip);
 void print_net(struct net* net);
 
+char* get_proto_name(unsigned int proto);
+#define proto2a get_proto_name
+
+
+
 #ifdef USE_MCAST
 /* Returns 1 if the given address is a multicast address */
 int is_mcast(struct ip_addr* ip);
@@ -211,6 +288,21 @@ inline static int ip_addr_any(struct ip_addr* ip)
 
 
 
+/* returns 1 if the given ip address is a loopback address
+ * 0 otherwise */
+inline static int ip_addr_loopback(struct ip_addr* ip)
+{
+       if (ip->af==AF_INET)
+               return ip->u.addr32[0]==htonl(INADDR_LOOPBACK);
+#ifdef USE_IPV6
+       else if (ip->af==AF_INET6)
+               return IN6_IS_ADDR_LOOPBACK((struct in6_addr*)ip->u.addr32);
+#endif /* USE_IPV6 */
+       return 0;
+}
+
+
+
 /* creates an ANY ip_addr (filled with 0, af and len properly set) */
 inline static void ip_addr_mk_any(int af, struct ip_addr* ip)
 {
@@ -290,7 +382,8 @@ static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
 
 
 /* compare 2 sockaddr_unions */
-static inline int su_cmp(union sockaddr_union* s1, union sockaddr_union* s2)
+static inline int su_cmp(const union sockaddr_union* s1,
+                                                const union sockaddr_union* s2)
 {
        if (s1->s.sa_family!=s2->s.sa_family) return 0;
        switch(s1->s.sa_family){
@@ -312,7 +405,7 @@ static inline int su_cmp(union sockaddr_union* s1, union sockaddr_union* s2)
 
 
 /* gets the port number (host byte order) */
-static inline unsigned short su_getport(union sockaddr_union* su)
+static inline unsigned short su_getport(const union sockaddr_union* su)
 {
        switch(su->s.sa_family){
                case AF_INET:
@@ -642,13 +735,13 @@ static inline char* su2a(union sockaddr_union* su, int su_len)
 {
        static char buf[SU2A_MAX_STR_SIZE];
        int offs;
-       
+
 #ifdef USE_IPV6
        if (unlikely(su->s.sa_family==AF_INET6)){
                if (unlikely(su_len<sizeof(su->sin6)))
                        return "<addr. error>";
                buf[0]='[';
-               offs=1+ip6tosbuf((unsigned char*)&su->sin6.sin6_addr, &buf[1],
+               offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
                                                        sizeof(buf)-4);
                buf[offs]=']';
                offs++;
@@ -664,6 +757,34 @@ static inline char* su2a(union sockaddr_union* su, int su_len)
        return buf;
 }
 
+#define SUIP2A_MAX_STR_SIZE  (IP6_MAX_STR_SIZE + 2 /* [] */ + 1 /* \0 */)
+/* returns an asciiz string containing the ip
+ *  (<ipv4_addr> or [<ipv6_addr>])
+ */
+static inline char* suip2a(union sockaddr_union* su, int su_len)
+{
+       static char buf[SUIP2A_MAX_STR_SIZE];
+       int offs;
+
+#ifdef USE_IPV6
+       if (unlikely(su->s.sa_family==AF_INET6)){
+               if (unlikely(su_len<sizeof(su->sin6)))
+                       return "<addr. error>";
+               buf[0]='[';
+               offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
+                                                       sizeof(buf)-4);
+               buf[offs]=']';
+               offs++;
+       }else
+#endif /* USE_IPV6*/
+       if (unlikely(su_len<sizeof(su->sin)))
+               return "<addr. error>";
+       else
+               offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
+       buf[offs]=0;
+       return buf;
+}
+
 
 
 /* converts an ip_addr structure to a hostent, returns pointer to internal
@@ -709,10 +830,17 @@ inline static void init_dst_from_rcv(struct dest_info* dst,
                dst->to=rcv->src_su;
                dst->id=rcv->proto_reserved1;
                dst->proto=rcv->proto;
+               dst->send_flags.f=0;
+               dst->send_flags.blst_imask=0;
 #ifdef USE_COMP
                dst->comp=rcv->comp;
 #endif
 }
 
+/**
+ * match ip address with net address and bitmask
+ * - return 0 on match, -1 otherwise
+ */
+int ip_addr_match_net(ip_addr_t *iaddr, ip_addr_t *naddr, int mask);
 
 #endif