anchor.diff:  -module(geoip).
   -author('wuhualiang@meituan.com').
   
  +-mode(compile).
  +
   -export([start/2]).
   
   -define(DEV, _).
   -ifdef(DEV).
   -export([http_response/2]).
  +-export([special_ip/1]).
  +-export([multicast_ip/1]).
   -endif.
   
   -define(IPS_FILE, "ips.dump").
  
positive.code: %%================================
  %% Geographic IP Informatin Server
  %%================================
  
negative.code:             gen_tcp:send(Sock, http_response(Json, Code)),
              gen_tcp:close(Sock),
              worker(Tid, Todo + 1)
      end.
  
  lookup(IP) when is_list(IP) ->
      case inet:parse_ipv4strict_address(IP) of
          {ok, {A, B, C, D}} ->
              if
                  A == 0;
                  A == 10;
                  A == 100, (B band 2#11000000) == 64;
                  A == 127;
                  [A, B] == [169, 254];
                  A == 172, (B band 2#11110000) == 16;
                  [A, B, C] == [192, 0, 0];
                  [A, B, C] == [192, 0, 2];
                  [A, B, C] == [192, 88, 99];
                  [A, B] == [192, 168];
                  A == 198, (B band 2#11111110) == 18;
                  [A, B, C] == [198, 51, 100];
                  [A, B, C] == [203, 0, 113];
                  (A band 2#11110000) == 240;
                  [A, B, C, D] == [255, 255, 255, 255] ->
                      special_ip(IP);
                  (A band 2#11110000) == 224 ->
                      multicast_ip(IP);
                  true ->
                      lookup_ets(IP)
              end;
          _ -> invalid_ip()
      end.
  
  lookup_ets(IP) ->
      ok.
  
  special_ip(IP) ->
      Json = "{\"province\":\"https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml\"," ++
             "\"city\":\"\"," ++ 
             "\"ip\":\"" ++ IP ++ "\"," ++
             "\"isp\":\"\"," ++
             "\"county\":\"\"," ++
             "\"country\":\"IANA Special-Purpose Address\"}",
      {200, Json}.
  
  multicast_ip(IP) ->
      Json = "{\"province\":\"https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml\"," ++
             "\"city\":\"\"," ++ 
             "\"ip\":\"" ++ IP ++ "\"," ++
             "\"isp\":\"\"," ++
             "\"county\":\"\"," ++
             "\"country\":\"IANA Multicast Address\"}",
      {200, Json}.
  
  invalid_ip() ->
      {400, "{\"message\":\"invalid ip.\"}"}.
  
  months() ->
      ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"].
  
  weekdays() ->
      ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].
  
  http_response(Code, Json) ->
      Status = case Code of
          200 -> "HTTP/1.1 200 OK\r\nServer: Erlang\r\n";
          400 -> "HTTP/1.1 BAD REQUEST\r\nServer: Erlang\r\n"
      end,
      {{Year, Month, Mday}, {Hour, Min, Sec}} = calendar:universal_time(),
      Wday = calendar:day_of_the_week({Year, Month, Mday}),
      Args = [lists:nth(Wday, weekdays()), Mday, lists:nth(Month, months()),
              Year, Hour, Min, Sec],
      Date = io_lib:format("Date: ~s, ~b ~s ~b ~b:~b:~b GMT\r\n", Args),
      lists:concat([Status, Date,
  