Procedure of gen_udp:open

./erts/preloaded/src/erlang.erl
1250 %% nif_error/1
1251 %% Shadowed by erl_bif_types: erlang:nif_error/1
1252 -spec erlang:nif_error(Reason) -> no_return() when
1253       Reason :: term().
1254 nif_error(_Reason) ->
1255     erlang:nif_error(undefined).
1256
1257 %% nif_error/2
1258 %% Shadowed by erl_bif_types: erlang:nif_error/2
1259 -spec erlang:nif_error(Reason, Args) -> no_return() when
1260       Reason :: term(),
1261       Args :: [term()].
1262 nif_error(_Reason, _Args) ->
1263     erlang:nif_error(undefined).
 
./erts/preloaded/src/erts_internal.erl
135 -spec erts_internal:port_control(Port, Operation, Data) -> Result when
136       Port :: port() | atom(),
137       Operation :: integer(),
138       Data :: iodata(),
139       Result :: string() | binary() | reference() | badarg.
140 port_control(_Port, _Operation, _Data) ->
141     erlang:nif_error(undefined).
 
./erts/preloaded/src/erlang.erl
3033 -spec port_control(Port, Operation, Data) -> iodata() | binary() when
3034       Port :: port() | atom(),
3035       Operation :: integer(),
3036       Data :: iodata().
3037
3038 port_control(Port, Operation, Data) ->
3039     case case erts_internal:port_control(Port, Operation, Data) of
3040          Ref when erlang:is_reference(Ref) -> receive {Ref, Res} -> Res end;
3041          Res -> Res
3042      end of
3043     badarg -> erlang:error(badarg, [Port, Operation, Data]);
3044     Result -> Result
3045     end.
 
lib/kernel/src/inet_int.hrl
 27 %% family codes to open
 28 -define(INET_AF_UNSPEC,       0).
 29 -define(INET_AF_INET,         1).
 30 -define(INET_AF_INET6,        2).
 31 -define(INET_AF_ANY,          3). % Fake for ANY in any address family
 32 -define(INET_AF_LOOPBACK,     4). % Fake for LOOPBACK in any address family
 33 -define(INET_AF_LOCAL,        5). % For Unix Domain address family
 34 -define(INET_AF_UNDEFINED,    6). % For any unknown address family

./erts/preloaded/src/prim_inet.erl
1690 enc_value(set, Type, Value)   ->         % Required for setopts
1691     enc_value_default(set, Type, Value);

1698 enc_value_default(Q, Type, Value) ->
1699     enc_value_1(Q, Type, Value).

1709 enc_value_1(_, Type, Value) ->
1710     enc_value_2(Type, Value).
1737 enc_value_2(addr, {any,Port}) ->
1738     [?INET_AF_ANY|?int16(Port)];
1739 enc_value_2(addr, {loopback,Port}) ->
1740     [?INET_AF_LOOPBACK|?int16(Port)];
1741 enc_value_2(addr, {IP,Port}) when tuple_size(IP) =:= 4 ->
1742     [?INET_AF_INET,?int16(Port)|ip4_to_bytes(IP)];
1743 enc_value_2(addr, {IP,Port}) when tuple_size(IP) =:= 8 ->
1744     [?INET_AF_INET6,?int16(Port)|ip6_to_bytes(IP)];
1745 enc_value_2(addr, {File,_}) when is_list(File); is_binary(File) ->
1746     [?INET_AF_LOCAL,iolist_size(File)|File];
1747 %%
1748 enc_value_2(addr, {inet,{any,Port}}) ->
1749     [?INET_AF_INET,?int16(Port),0,0,0,0];
1750 enc_value_2(addr, {inet,{loopback,Port}}) ->
1751     [?INET_AF_INET,?int16(Port),127,0,0,1];
1752 enc_value_2(addr, {inet,{IP,Port}}) ->
1753     [?INET_AF_INET,?int16(Port)|ip4_to_bytes(IP)];
1754 enc_value_2(addr, {inet6,{any,Port}}) ->
1755     [?INET_AF_INET6,?int16(Port),0,0,0,0,0,0,0,0];
1756 enc_value_2(addr, {inet6,{loopback,Port}}) ->
1757     [?INET_AF_INET6,?int16(Port),0,0,0,0,0,0,0,1];
1758 enc_value_2(addr, {inet6,{IP,Port}}) ->
1759     [?INET_AF_INET6,?int16(Port)|ip6_to_bytes(IP)];
1760 enc_value_2(addr, {local,Addr}) ->
1761     %% A binary is passed as is, but anything else will be
1762     %% regarded as a filename and therefore encoded according to
1763     %% the current system filename encoding mode.
1764     Bin =
1765     if
1766         is_binary(Addr) ->
1767         Addr;
1768         true ->
1769         unicode:characters_to_binary(
1770           Addr, file:native_name_encoding())
1771     end,
1772     [?INET_AF_LOCAL,byte_size(Bin),Bin];
1773 %%


./erts/preloaded/src/prim_inet.erl
1536 type_value_default(Q, Type, Value) ->
1537     type_value_1(Q, Type, Value).
1538
1539 type_value_1(Q, {record,Types}, undefined) ->
1540     type_value_record(Q, Types,
1541               erlang:make_tuple(tuple_size(Types), undefined), 2);
1542 type_value_1(Q, {record,Types}, Values)
1543   when tuple_size(Types) =:= tuple_size(Values) ->
1544     type_value_record(Q, Types, Values, 2);
1545 type_value_1(Q, Types, Values)
1546   when tuple_size(Types) =:= tuple_size(Values) ->
1547     type_value_tuple(Q, Types, Values, 1);
1548 type_value_1(_, Type, Value) ->
1549     type_value_2(Type, Value).


1566 %% Simple run-time type-checking of (option) values: type -vs- value:
1567 %% NB: the LHS is the TYPE, not the option name!
1568 %%
1569 %% Returns true | false | throw(ErrorReason) only for record types
1570 %%
1571 type_value_2(undefined, _)                            -> false;
1572 %%
1573 type_value_2(bool, true)                              -> true;
1574 type_value_2(bool, false)                             -> true;
1575 type_value_2(bool8, true)                             -> true;
1576 type_value_2(bool8, false)                            -> true;
1577 type_value_2(int, X) when is_integer(X)               -> true;
1578 type_value_2(uint, X) when is_integer(X), X >= 0      -> true;
1579 type_value_2(uint32, X) when X band 16#ffffffff =:= X -> true;
1580 type_value_2(uint24, X) when X band 16#ffffff =:= X   -> true;
1581 type_value_2(uint16, X) when X band 16#ffff =:= X     -> true;
1582 type_value_2(uint8, X)  when X band 16#ff =:= X       -> true;
1583 type_value_2(time, infinity)                          -> true;
1584 type_value_2(time, X) when is_integer(X), X >= 0      -> true;
1585 type_value_2(ip,{A,B,C,D}) when ?ip(A,B,C,D)          -> true;
1586 %%
1587 type_value_2(addr, {any,Port}) ->
1588     type_value_2(uint16, Port);
1589 type_value_2(addr, {loopback,Port}) ->
1590     type_value_2(uint16, Port);
1591 type_value_2(addr, {IP,_} = Addr) when tuple_size(IP) =:= 4 ->
1592     type_value_2(addr, {inet,Addr});
1593 type_value_2(addr, {IP,_} = Addr) when tuple_size(IP) =:= 8 ->
1594     type_value_2(addr, {inet6,Addr});
1595 type_value_2(addr, {Local,_}) when is_list(Local); is_binary(Local) ->
1596     type_value_2(addr, {local,Local});
1597 %%
1598 type_value_2(addr, {Family,{Tag,Port}})
1599   when (Family =:= inet orelse Family =:= inet6) andalso
1600        (Tag =:= any orelse Tag =:= loopback) ->
1601     type_value_2(uint16, Port);
1602 type_value_2(addr, {inet,{{A,B,C,D},Port}})
1603   when ?ip(A,B,C,D) ->
1604     type_value_2(uint16, Port);
1605 type_value_2(addr, {inet6,{{A,B,C,D,E,F,G,H},Port}})
1606   when ?ip6(A,B,C,D,E,F,G,H) ->

 1607     type_value_2(uint16, Port);
1608 type_value_2(addr, {local,Addr}) ->
1609     if
1610     is_binary(Addr) ->
1611         byte_size(Addr) =< 255;
1612     true ->
1613         try
1614         %% We either get a badarg from byte_size
1615         %% or from characters_to_binary
1616         byte_size(
1617           unicode:characters_to_binary(
1618             Addr, file:native_name_encoding()))
1619         of
1620         N when N =< 255 ->
1621             true;
1622         _ ->
1623             false
1624         catch error:badarg ->
1625             false
1626         end
1627     end;

lib/kernel/src/inet_int.hrl
 65 %% request codes (erlang:port_control/3)
 66 -define(INET_REQ_OPEN,          1).
 67 -define(INET_REQ_CLOSE,         2).
 68 -define(INET_REQ_CONNECT,       3).
 69 -define(INET_REQ_PEER,          4).
 70 -define(INET_REQ_NAME,          5).
 71 -define(INET_REQ_BIND,          6).
 72 -define(INET_REQ_SETOPTS,       7).
 73 -define(INET_REQ_GETOPTS,       8).
 74 -define(INET_REQ_GETIX,         9).

./erts/preloaded/src/prim_inet.erl
 202 bind(S, Addr, _) when is_port(S), tuple_size(Addr) =:= 2 ->
 203     case type_value(set, addr, Addr) of
 204     true ->
 205         case ctl_cmd(S,?INET_REQ_BIND,enc_value(set, addr, Addr)) of
 206         {ok, [P1,P0]} -> {ok, ?u16(P1, P0)};
 207         {error, _} = Error -> Error
 208         end;
 209     false ->
 210         {error, einval}
 211     end;
 212 bind(S, IP, Port) ->
 213     bind(S, {IP, Port}, 0).


2441 %% Control command
2442 ctl_cmd(Port, Cmd, Args) ->
2443     ?DBG_FORMAT("prim_inet:ctl_cmd(~p, ~p, ~p)~n", [Port,Cmd,Args]),
2444     Result =
2445     try erlang:port_control(Port, Cmd, Args) of
2446         [?INET_REP_OK|Reply]  -> {ok,Reply};
2447         [?INET_REP]  -> inet_reply;
2448         [?INET_REP_ERROR|Err] -> {error,list_to_atom(Err)}
2449     catch
2450         error:_               -> {error,einval}
2451     end,
2452         ?DBG_FORMAT("prim_inet:ctl_cmd() -> ~p~n", [Result]),
2453     Result.


lib/kernel/src/inet.erl

1318 -spec open(Fd_or_OpenOpts :: integer() | list(),
1319        Addr ::
1320          socket_address() |
1321          {ip_address() | 'any' | 'loopback', % Unofficial
1322           port_number()} |
1323          {inet, % Unofficial
1324           {ip4_address() | 'any' | 'loopback',
1325            port_number()}} |
1326          {inet6, % Unofficial
1327           {ip6_address() | 'any' | 'loopback',
1328            port_number()}} |
1329          undefined, % Internal - no bind()
1330        Port :: port_number(),
1331        Opts :: [socket_setopt()],
1332        Protocol :: socket_protocol(),
1333        Family :: address_family(),
1334        Type :: socket_type(),
1335        Module :: atom()) ->
1336     {'ok', socket()} | {'error', posix()}.
1337
1338 open(FdO, Addr, Port, Opts, Protocol, Family, Type, Module)
1339   when is_integer(FdO), FdO < 0;
1340        is_list(FdO) ->
1341     OpenOpts =
1342     if  is_list(FdO) -> FdO;
1343         true -> []
1344     end,
1345     case prim_inet:open(Protocol, Family, Type, OpenOpts) of
1346     {ok,S} ->
1347         case prim_inet:setopts(S, Opts) of
1348         ok when Addr =:= undefined ->
1349             inet_db:register_socket(S, Module),
1350             {ok,S};
1351         ok ->
1352             case bind(S, Addr, Port) of
1353             {ok, _} ->
1354                 inet_db:register_socket(S, Module),
1355                 {ok,S};
1356             Error  ->
1357                 prim_inet:close(S),
1358                 Error
1359             end;
1360         Error  ->
1361             prim_inet:close(S),
1362             Error
1363         end;
1364     Error ->
1365         Error
1366     end;
1367 open(Fd, Addr, Port, Opts, Protocol, Family, Type, Module)
1368   when is_integer(Fd) ->
1369     fdopen(Fd, Addr, Port, Opts, Protocol, Family, Type, Module).

1371 bind(S, Addr, Port) when is_list(Addr) ->
1372     bindx(S, Addr, Port);
1373 bind(S, Addr, Port) ->
1374     prim_inet:bind(S, Addr, Port).
1375
1376 bindx(S, [Addr], Port0) ->
1377     {IP, Port} = set_bindx_port(Addr, Port0),
1378     prim_inet:bind(S, IP, Port);
1379 bindx(S, Addrs, Port0) ->
1380     [{IP, Port} | Rest] = [set_bindx_port(Addr, Port0) || Addr <- Addrs],
1381     case prim_inet:bind(S, IP, Port) of
1382     {ok, AssignedPort} when Port =:= 0 ->
1383         %% On newer Linux kernels, Solaris and FreeBSD, calling
1384         %% bindx with port 0 is ok, but on SuSE 10, it results in einval
1385         Rest2 = [change_bindx_0_port(Addr, AssignedPort) || Addr <- Rest],
1386         prim_inet:bind(S, add, Rest2);
1387     {ok, _} ->
1388         prim_inet:bind(S, add, Rest);
1389     Error ->
1390         Error
1391     end.
1392
1393 set_bindx_port({_IP, _Port}=Addr, _OtherPort) ->
1394     Addr;
1395 set_bindx_port(IP, Port) ->
1396     {IP, Port}.

lib/kernel/src/inet_udp.erl

31 -define(FAMILY, inet).
 32 -define(PROTO, udp).
 33 -define(TYPE, dgram).
 34 -define(RECBUF, (8*1024))

37 %% inet_udp port lookup
 38 getserv(Port) when is_integer(Port) -> {ok, Port};
 39 getserv(Name) when is_atom(Name) -> inet:getservbyname(Name, ?PROTO).

48 -spec open(_) -> {ok, inet:socket()} | {error, atom()}.
 49 open(Port) -> open(Port, []).
 50
 51 -spec open(_, _) -> {ok, inet:socket()} | {error, atom()}.
 52 open(Port, Opts) ->
 53     case inet:udp_options(
 54        [{port,Port}, {recbuf, ?RECBUF} | Opts],
 55        ?MODULE) of
 56     {error, Reason} -> exit(Reason);
 57     {ok,
 58      #udp_opts{
 59         fd = Fd,
 60         ifaddr = BAddr = {A,B,C,D},
 61         port = BPort,
 62         opts = SockOpts}}
 63       when ?ip(A,B,C,D), ?port(BPort) ->
 64         inet:open(
 65           Fd, BAddr, BPort, SockOpts, ?PROTO, ?FAMILY, ?TYPE, ?MODULE);
 66     {ok, _} -> exit(badarg)
 67     end.


lib/kernel/src/inet_config.hrl

21 %% Configuration constants
 22
 23 -define(DEFAULT_ETC,       "/etc").
 24 -define(DEFAULT_SERVICES,  "services").
 25 -define(DEFAULT_RPC,       "rpc").
 26 -define(DEFAULT_HOSTS,     "hosts").
 27 -define(DEFAULT_RESOLV,    "resolv.conf").
 28 -define(DEFAULT_PROTOCOLS, "protocols").
 29 -define(DEFAULT_NETMASKS,  "netmasks").
 30 -define(DEFAULT_NETWORKS,  "networks").
 31
 32 -define(DEFAULT_UDP_MODULE,  inet_udp).
 33 -define(DEFAULT_TCP_MODULE,  inet_tcp).
 34 -define(DEFAULT_SCTP_MODULE, inet_sctp).

lib/kernel/src/inet_db.erl

 268 udp_module() -> db_get(udp_module).

 544 db_get(Name) ->
 545     case ets:lookup(inet_db, Name) of
 546     [] -> undefined;
 547     [{_,Val}] -> Val
 548     end.


 870 reset_db(Db) ->
 871     ets:insert(Db, {hostname, []}),
 872     ets:insert(Db, {res_ns, []}),
 873     ets:insert(Db, {res_alt_ns, []}),
 874     ets:insert(Db, {res_search, []}),
 875     ets:insert(Db, {res_domain, ""}),
 876     ets:insert(Db, {res_lookup, []}),
 877     ets:insert(Db, {res_recurse, true}),
 878     ets:insert(Db, {res_usevc, false}),
 879     ets:insert(Db, {res_id, 0}),
 880     ets:insert(Db, {res_retry, ?RES_RETRY}),
 881     ets:insert(Db, {res_timeout, ?RES_TIMEOUT}),
 882     ets:insert(Db, {res_inet6, false}),
 883     ets:insert(Db, {res_edns, false}),
 884     ets:insert(Db, {res_udp_payload_size, ?DNS_UDP_PAYLOAD_SIZE}),
 885     ets:insert(Db, {cache_size, ?CACHE_LIMIT}),
 886     ets:insert(Db, {cache_refresh_interval,?CACHE_REFRESH}),
 887     ets:insert(Db, {socks5_server, ""}),
 888     ets:insert(Db, {socks5_port, ?IPPORT_SOCKS}),
 889     ets:insert(Db, {socks5_methods, [none]}),
 890     ets:insert(Db, {socks5_noproxy, []}),
 891     ets:insert(Db, {tcp_module,  ?DEFAULT_TCP_MODULE}),
 892     ets:insert(Db, {udp_module,  ?DEFAULT_UDP_MODULE}),
 893     ets:insert(Db, {sctp_module, ?DEFAULT_SCTP_MODULE}).


lib/kernel/src/inet.erl

1065 mod(Opts, Tag, Address, Map) ->
1066     mod(Opts, Tag, Address, Map, undefined, []).
1067 %%
1068 mod([{Tag, M}|Opts], Tag, Address, Map, Mod, Acc) ->
1069     mod(Opts, Tag, Address, Map, Mod, Acc, M);
1070 mod([{T, _} = Opt|Opts], Tag, _Address, Map, Mod, Acc)
1071   when T =:= ip; T =:= ifaddr->
1072     mod(Opts, Tag, Opt, Map, Mod, [Opt|Acc]);
1073 mod([Family|Opts], Tag, Address, Map, Mod, Acc) when is_atom(Family) ->
1074     case Map of
1075     #{Family := M} ->
1076         mod(Opts, Tag, Address, Map, Mod, Acc, M);
1077     #{} ->
1078         mod(Opts, Tag, Address, Map, Mod, [Family|Acc])
1079     end;
1080 mod([Opt|Opts], Tag, Address, Map, Mod, Acc) ->
1081     mod(Opts, Tag, Address, Map, Mod, [Opt|Acc]);
1082 mod([], Tag, Address, Map, undefined, Acc) ->
1083     {case Address of
1084      {_, {local, _}} ->
1085          case Map of
1086          #{local := Mod} ->
1087              Mod;
1088          #{} ->
1089              inet_db:Tag()
1090          end;
1091      {_, IP} when tuple_size(IP) =:= 8 ->
1092          #{inet := IPv4Mod} = Map,
1093          %% Get the mod, but IPv6 address overrides default IPv4
1094          case inet_db:Tag() of
1095          IPv4Mod ->
1096              #{inet6 := IPv6Mod} = Map,
1097              IPv6Mod;
1098          Mod ->
1099              Mod
1100          end;
1101      _ ->
1102          inet_db:Tag()
1103      end, lists:reverse(Acc)};
1104 mod([], _Tag, _Address, _Map, Mod, Acc) ->
1105     {Mod, lists:reverse(Acc)}.
1106 %%
1107 mod(Opts, Tag, Address, Map, undefined, Acc, M) ->
1108     mod(Opts, Tag, Address, Map, M, Acc);
1109 mod(Opts, Tag, Address, Map, Mod, Acc, _M) ->
1110     mod(Opts, Tag, Address, Map, Mod, Acc).


900 udp_module(Opts) ->
 901     mod(
 902       Opts, udp_module, undefined,
 903       #{inet => inet_udp, inet6 => inet6_udp, local => local_udp}).

lib/kernel/src/gen_udp.erl
 92 -spec open(Port, Opts) -> {ok, Socket} | {error, Reason} when
 93       Port :: inet:port_number(),
 94       Opts :: [Option],
 95       Option :: {ip, inet:socket_address()}
 96               | {fd, non_neg_integer()}
 97               | {ifaddr, inet:socket_address()}
 98               | inet:address_family()
 99               | {port, inet:port_number()}
100               | option(),
101       Socket :: socket(),
102       Reason :: inet:posix().
103
104 open(Port, Opts0) ->
105     {Mod, Opts} = inet:udp_module(Opts0),
106     {ok, UP} = Mod:getserv(Port),
107     Mod:open(UP, Opts).


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值