Skip to content

Commit d5c274e

Browse files
committed
remove most of Ip_address: and depend on ocaml-ipaddr
1 parent 0874888 commit d5c274e

File tree

10 files changed

+19
-199
lines changed

10 files changed

+19
-199
lines changed

Makefile.options

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ ifeq "$(PREEMPTIVE)" "YES"
2929
LWT_EXTRA_PACKAGE:=lwt.extra
3030
endif
3131

32-
BASE_PACKAGE := lwt
32+
BASE_PACKAGE := lwt ipaddr
3333

3434
SERVER_PACKAGE := lwt.ssl \
3535
${LWT_EXTRA_PACKAGE} \
36+
ipaddr \
3637
netstring \
3738
netstring-pcre \
3839
findlib \
@@ -51,4 +52,3 @@ INITPACKAGE := \"$(shell ${OCAMLFIND} query -p-format -recursive \
5152
\"${PROJECTNAME}.baselib\"; \
5253
\"${PROJECTNAME}.http\"; \
5354
\"${PROJECTNAME}\"; \
54-

src/baselib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include ../../Makefile.config
22

3-
LIBS := -package lwt.unix,netstring,netstring-pcre,cryptokit,findlib,tyxml,lwt.syntax,${LWT_EXTRA_PACKAGE}
3+
LIBS := -package lwt.unix,netstring,netstring-pcre,cryptokit,findlib,tyxml,lwt.syntax,${LWT_EXTRA_PACKAGE},ipaddr
44
OCAMLC := $(OCAMLFIND) ocamlc${BYTEDBG} ${THREAD}
55
OCAMLOPT := $(OCAMLFIND) ocamlopt ${OPTDBG} ${THREAD}
66
OCAMLDOC := $(OCAMLFIND) ocamldoc

src/baselib/ocsigen_lib.ml

Lines changed: 0 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -23,158 +23,8 @@ module String = String_base
2323
(*****************************************************************************)
2424

2525
module Ip_address = struct
26-
27-
type t =
28-
| IPv4 of int32
29-
| IPv6 of int64 * int64
30-
31-
exception Invalid_ipaddress of string
32-
33-
let parse s =
34-
let s = String.lowercase s in
35-
let n = String.length s in
36-
let is6 = String.contains s ':' in
37-
let failwith fmt = Printf.ksprintf (fun s -> raise (Invalid_ipaddress s)) fmt in
38-
39-
let rec parse_hex i accu =
40-
match (if i < n then s.[i] else ':') with
41-
| '0'..'9' as c -> parse_hex (i+1) (16*accu+(int_of_char c)-48)
42-
| 'a'..'f' as c -> parse_hex (i+1) (16*accu+(int_of_char c)-87)
43-
| _ -> (i, accu)
44-
in
45-
let rec parse_dec i accu =
46-
match (if i < n then s.[i] else '.') with
47-
| '0'..'9' as c -> parse_dec (i+1) (10*accu+(int_of_char c)-48)
48-
| _ -> (i, accu)
49-
in
50-
let rec next_is_dec i =
51-
if i < n then
52-
match s.[i] with
53-
| ':' -> false
54-
| '.' -> true
55-
| _ -> next_is_dec (i+1)
56-
else false
57-
in
58-
let rec parse_component i accu nb =
59-
if i < n then
60-
if next_is_dec i then
61-
let (i1, a) = parse_dec i 0 in
62-
if i1 = i || (i1 < n && s.[i1] <> '.') then failwith "invalid dot notation in %s (1)" s;
63-
let (i2, b) = parse_dec (i1+1) 0 in
64-
if i2 = i1 then failwith "invalid dot notation in %s (2)" s;
65-
let component =
66-
if a < 0 || a > 255 || b < 0 || b > 255 then
67-
failwith "invalid dot notation in %s (3)" s
68-
else (a lsl 8) lor b
69-
in
70-
if i2 < n-1 && (s.[i2] = ':' || s.[i2] = '.') then
71-
parse_component (i2+1) (component::accu) (nb+1)
72-
else
73-
(i2, component::accu, nb+1)
74-
else if s.[i] = ':' then
75-
parse_component (i+1) ((-1)::accu) nb
76-
else
77-
let (i1, a) = parse_hex i 0 in
78-
if a < 0 || a > 0xffff then failwith "invalid colon notation in %s" s;
79-
if i1 = i then
80-
(i, accu, nb)
81-
else if i1 < n-1 && s.[i1] = ':' then
82-
parse_component (i1+1) (a::accu) (nb+1)
83-
else
84-
(i1, a::accu, nb+1)
85-
else
86-
(i, accu, nb)
87-
in
88-
89-
let (i, addr_list, size_list) =
90-
if 1 < n && s.[0] = ':' && s.[1] = ':' then
91-
parse_component 2 [-1] 0
92-
else
93-
parse_component 0 [] 0
94-
in
95-
96-
if size_list > 8 then failwith "too many components in %s" s;
97-
98-
let maybe_mask =
99-
if i < n && s.[i] = '/' then
100-
let (i1, m) = parse_dec (i+1) 0 in
101-
if i1 = i+1 || i1 < n || m < 0 || m > (if is6 then 128 else 32) then
102-
failwith "invalid /n suffix in %s" s
103-
else
104-
Some m
105-
else if i < n then
106-
failwith "invalid suffix in %s (from index %i)" s i
107-
else
108-
None
109-
in
110-
111-
if is6 then
112-
let (++) a b = Int64.logor (Int64.shift_left a 16) (Int64.of_int b) in
113-
let normalized =
114-
let rec aux_add n accu =
115-
if n = 0 then accu else aux_add (n-1) (0::accu)
116-
in
117-
let rec aux_rev accu = function
118-
| [] -> accu
119-
| (-1)::q -> aux_rev (aux_add (8-size_list) accu) q
120-
| a::q -> aux_rev (a::accu) q
121-
in
122-
aux_rev [] addr_list
123-
in
124-
let maybe_mask = match maybe_mask with
125-
| Some n when n > 64 ->
126-
Some (IPv6 (Int64.minus_one, Int64.shift_left Int64.minus_one (128-n)))
127-
| Some n ->
128-
Some (IPv6 (Int64.shift_left Int64.minus_one (64-n), Int64.zero))
129-
| None -> None
130-
in
131-
match normalized with
132-
| [a; b; c; d; e; f; g; h] ->
133-
IPv6 (Int64.zero ++ a ++ b ++ c ++ d,
134-
Int64.zero ++ e ++ f ++ g ++ h), maybe_mask
135-
| _ -> failwith "invalid IPv6 address: %s (%d components)" s (List.length normalized)
136-
else
137-
let (++) a b = Int32.logor (Int32.shift_left a 16) (Int32.of_int b) in
138-
let maybe_mask = match maybe_mask with
139-
| Some n ->
140-
Some (IPv4 (Int32.shift_left Int32.minus_one (32-n)))
141-
| None -> None
142-
in
143-
match addr_list with
144-
| [b; a] ->
145-
IPv4 (Int32.zero ++ a ++ b), maybe_mask
146-
| _ -> failwith "invalid IPv4 address: %s" s
147-
148-
149-
let match_ip (base, mask) ip =
150-
match ip, base, mask with
151-
| IPv4 a, IPv4 b, Some (IPv4 m) -> Int32.logand a m = Int32.logand b m
152-
| IPv4 a, IPv4 b, None -> a = b
153-
| IPv6 (a1,a2), IPv6 (b1,b2), Some (IPv6 (m1,m2)) ->
154-
Int64.logand a1 m1 = Int64.logand b1 m1 &&
155-
Int64.logand a2 m2 = Int64.logand b2 m2
156-
| IPv6 (a1,a2), IPv6 (b1,b2), None -> a1 = b1 && a2 = b2
157-
| IPv6 (a1,a2), IPv4 b, c
158-
when a1 = 0L && Int64.logand a2 0xffffffff00000000L = 0xffff00000000L ->
159-
(* might be insecure, cf
160-
http://tools.ietf.org/internet-drafts/draft-itojun-v6ops-v4mapped-harmful-02.txt *)
161-
let a = Int64.to_int32 a2 in
162-
begin match c with
163-
| Some (IPv4 m) -> Int32.logand a m = Int32.logand b m
164-
| Some (IPv6 _) -> invalid_arg "match_ip"
165-
| None -> a = b
166-
end
167-
| _ -> false
168-
169-
let network_of_ip ip mask4 (mask61, mask62) = match ip with
170-
| IPv4 a -> IPv4 (Int32.logand a mask4)
171-
| IPv6 (a, b) -> IPv6 (Int64.logand a mask61, Int64.logand b mask62)
172-
17326
exception No_such_host
17427

175-
let inet6_addr_loopback =
176-
fst (parse (Unix.string_of_inet_addr Unix.inet6_addr_loopback))
177-
17828
let get_inet_addr ?(v6=false) host =
17929
let rec aux = function
18030
| [] -> Lwt.fail No_such_host
@@ -186,22 +36,6 @@ module Ip_address = struct
18636
(Lwt_unix.getaddrinfo host "" options)
18737
aux
18838

189-
(*
190-
let getnameinfo ia p =
191-
try
192-
Lwt_unix.getnameinfo (Unix.ADDR_INET (ia, p)) [Unix.NI_NAMEREQD] >>= fun r ->
193-
Lwt.return r.Unix.ni_hostname
194-
with
195-
| Not_found ->
196-
let hs = Unix.string_of_inet_addr ia in
197-
Lwt.return
198-
(if String.length hs > 7 && String.sub hs 0 7 = "::ffff:"
199-
then String.sub hs 7 (String.length hs - 7)
200-
else if String.contains hs ':'
201-
then "["^hs^"]"
202-
else hs)
203-
204-
*)
20539
end
20640

20741
(*****************************************************************************)

src/baselib/ocsigen_lib.mli

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,8 @@ val make_cryptographic_safe_string : unit -> string
3636
module String : module type of String_base
3737

3838
module Ip_address : sig
39-
40-
type t =
41-
| IPv4 of int32
42-
| IPv6 of int64 * int64
43-
44-
(* exception Invalid_ipaddress of string *)
45-
46-
val parse : string -> t * (t option)
47-
val match_ip : t * (t option) -> t -> bool
48-
val network_of_ip : t -> int32 -> int64 * int64 -> t
49-
5039
exception No_such_host
51-
52-
val inet6_addr_loopback : t
53-
5440
val get_inet_addr : ?v6:bool -> string -> Unix.inet_addr Lwt.t
55-
56-
(* val getnameinfo : Unix.inet_addr -> int -> string Lwt.t *)
57-
5841
end
5942

6043
module Filename : sig

src/extensions/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
include ../../Makefile.config
22

33
PACKAGE := lwt.unix \
4+
ipaddr \
45
lwt.ssl \
56
lwt.react \
67
netstring \

src/extensions/accesscontrol.ml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,18 @@ open Ocsigen_http_frame
4343
let rec parse_condition = function
4444

4545
| Element ("ip", ["value", s], []) ->
46-
let ip_with_mask =
46+
let prefix =
4747
try
48-
Ip_address.parse s
49-
with Failure _ ->
50-
badconfig "Bad ip/netmask [%s] in <ip> condition" s
48+
Ipaddr.Prefix.of_string_exn s
49+
with Ipaddr.Parse_error _ ->
50+
try
51+
let ip = Ipaddr.of_string_exn s in
52+
Ipaddr.Prefix.of_addr ip
53+
with _ ->
54+
badconfig "Bad ip/netmask [%s] in <ip> condition" s
5155
in
5256
(fun ri ->
53-
let r =
54-
Ip_address.match_ip ip_with_mask
55-
(Lazy.force ri.ri_remote_ip_parsed)
57+
let r = Ipaddr.mem prefix (Lazy.force ri.ri_remote_ip_parsed)
5658
in
5759
if r then
5860
Ocsigen_messages.debug2 (sprintf "--Access control (ip): %s matches %s" ri.ri_remote_ip s)
@@ -230,10 +232,10 @@ let parse_config parse_fun = function
230232
| Element ("nextsite", [], []) ->
231233
(function
232234
| Ocsigen_extensions.Req_found (_, r) ->
233-
Lwt.return (Ocsigen_extensions.Ext_found_stop
235+
Lwt.return (Ocsigen_extensions.Ext_found_stop
234236
(fun () -> Lwt.return r))
235237
| Ocsigen_extensions.Req_not_found (err, ri) ->
236-
Lwt.return (Ocsigen_extensions.Ext_stop_site
238+
Lwt.return (Ocsigen_extensions.Ext_stop_site
237239
(Ocsigen_cookies.Cookies.empty, 404)))
238240

239241
| Element ("nexthost", [], []) ->

src/files/META.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ package "ext" (
100100

101101
package "accesscontrol" (
102102
exists_if = "accesscontrol.cmo,accesscontrol.cmx"
103-
requires = "ocsigenserver"
103+
requires = "ocsigenserver,ipaddr"
104104
version = "[distributed with Ocsigen server]"
105105
description = "Filtering HTTP requests"
106106
archive(byte) = "accesscontrol.cmo"

src/server/ocsigen_extensions.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ type request_info =
216216
ri_files: (config_info -> (string * file_info) list Lwt.t) option; (** Files sent in the request (multipart data). None if other content type or no content. *)
217217
ri_remote_inet_addr: Unix.inet_addr; (** IP of the client *)
218218
ri_remote_ip: string; (** IP of the client *)
219-
ri_remote_ip_parsed: Ip_address.t Lazy.t; (** IP of the client, parsed *)
219+
ri_remote_ip_parsed: Ipaddr.t Lazy.t; (** IP of the client, parsed *)
220220
ri_remote_port: int; (** Port used by the client *)
221221
ri_forward_ip: string list; (** IPs of gateways the request went throught *)
222222
ri_server_port: int; (** Port of the request (server) *)

src/server/ocsigen_extensions.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ type request_info =
164164
ri_files: (config_info -> (string * file_info) list Lwt.t) option; (** Files sent in the request (multipart data). None if other content type or no content. *)
165165
ri_remote_inet_addr: Unix.inet_addr; (** IP of the client *)
166166
ri_remote_ip: string; (** IP of the client *)
167-
ri_remote_ip_parsed: Ip_address.t Lazy.t; (** IP of the client, parsed *)
167+
ri_remote_ip_parsed: Ipaddr.t Lazy.t; (** IP of the client, parsed *)
168168
ri_remote_port: int; (** Port used by the client *)
169169
ri_forward_ip: string list; (** IPs of gateways the request went throught *)
170170
ri_server_port: int; (** Port of the request (server) *)

src/server/ocsigen_server.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ let get_request_infos
382382
ri_files = files;
383383
ri_remote_inet_addr = client_inet_addr;
384384
ri_remote_ip = ipstring;
385-
ri_remote_ip_parsed = lazy (fst (Ip_address.parse ipstring));
385+
ri_remote_ip_parsed = lazy (Ipaddr.of_string_exn ipstring);
386386
ri_remote_port = port_of_sockaddr sockaddr;
387387
ri_forward_ip = [];
388388
ri_server_port = port;

0 commit comments

Comments
 (0)