⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sock.c

📁 An implementation of the TCP/IP protocol suite for the LINUX operating system. INET is implemented u
💻 C
📖 第 1 页 / 共 5 页
字号:
1141   cli(); /* avoid the race condition */
1142   while(sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) 
1143   {
1144         interruptible_sleep_on(sk->sleep);
1145         if (current->signal & ~current->blocked) {
1146                 sti();
1147                 return(-ERESTARTSYS);
1148         }
1149         /* This fixes a nasty in the tcp/ip code. There is a hideous hassle with
1150            icmp error packets wanting to close a tcp or udp socket. */
1151         if(sk->err && sk->protocol == IPPROTO_TCP)
1152         {
1153                 sti();
1154                 sock->state = SS_UNCONNECTED;
1155                 err = -sk->err;
1156                 sk->err=0;
1157                 return err; /* set by tcp_err() */
1158         }
1159   }
1160   sti();
1161   sock->state = SS_CONNECTED;
1162 
1163   if (sk->state != TCP_ESTABLISHED && sk->err) {
1164         sock->state = SS_UNCONNECTED;
1165         err=sk->err;
1166         sk->err=0;
1167         return(-err);
1168   }
1169   return(0);
1170 }
1171 
1172 
1173 static int
1174 inet_socketpair(struct socket *sock1, struct socket *sock2)
1175 {
1176   return(-EOPNOTSUPP);
1177 }
1178 
1179 
1180 static int
1181 inet_accept(struct socket *sock, struct socket *newsock, int flags)
1182 {
1183   struct sock *sk1, *sk2;
1184   int err;
1185 
1186   sk1 = (struct sock *) sock->data;
1187   if (sk1 == NULL) {
1188         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1189         return(0);
1190   }
1191 
1192   /*
1193    * We've been passed an extra socket.
1194    * We need to free it up because the tcp module creates
1195    * it's own when it accepts one.
1196    */
1197   if (newsock->data) kfree_s(newsock->data, sizeof(struct sock));
1198   newsock->data = NULL;
1199 
1200   if (sk1->prot->accept == NULL) return(-EOPNOTSUPP);
1201 
1202   /* Restore the state if we have been interrupted, and then returned. */
1203   if (sk1->pair != NULL ) {
1204         sk2 = sk1->pair;
1205         sk1->pair = NULL;
1206   } else {
1207         sk2 = sk1->prot->accept(sk1,flags);
1208         if (sk2 == NULL) {
1209                 if (sk1->err <= 0)
1210                         printk("Warning sock.c:sk1->err <= 0.  Returning non-error.\n");
1211                 err=sk1->err;
1212                 sk1->err=0;
1213                 return(-err);
1214         }
1215   }
1216   newsock->data = (void *)sk2;
1217   sk2->sleep = newsock->wait;
1218   newsock->conn = NULL;
1219   if (flags & O_NONBLOCK) return(0);
1220 
1221   cli(); /* avoid the race. */
1222   while(sk2->state == TCP_SYN_RECV) {
1223         interruptible_sleep_on(sk2->sleep);
1224         if (current->signal & ~current->blocked) {
1225                 sti();
1226                 sk1->pair = sk2;
1227                 sk2->sleep = NULL;
1228                 newsock->data = NULL;
1229                 return(-ERESTARTSYS);
1230         }
1231   }
1232   sti();
1233 
1234   if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) {
1235 
1236         err = -sk2->err;
1237         sk2->err=0;
1238         destroy_sock(sk2);
1239         newsock->data = NULL;
1240         return(err);
1241   }
1242   newsock->state = SS_CONNECTED;
1243   return(0);
1244 }
1245 
1246 
1247 static int
1248 inet_getname(struct socket *sock, struct sockaddr *uaddr,
1249                  int *uaddr_len, int peer)
1250 {
1251   struct sockaddr_in sin;
1252   struct sock *sk;
1253   int len;
1254   int err;
1255   
1256   
1257   err = verify_area(VERIFY_WRITE,uaddr_len,sizeof(long));
1258   if(err)
1259         return err;
1260         
1261   len=get_fs_long(uaddr_len);
1262   
1263   err = verify_area(VERIFY_WRITE, uaddr, len);
1264   if(err)
1265         return err;
1266         
1267   /* Check this error. */
1268   if (len < sizeof(sin)) return(-EINVAL);
1269 
1270   sin.sin_family = AF_INET;
1271   sk = (struct sock *) sock->data;
1272   if (sk == NULL) {
1273         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1274         return(0);
1275   }
1276   if (peer) {
1277         if (!tcp_connected(sk->state)) return(-ENOTCONN);
1278         sin.sin_port = sk->dummy_th.dest;
1279         sin.sin_addr.s_addr = sk->daddr;
1280   } else {
1281         sin.sin_port = sk->dummy_th.source;
1282         if (sk->saddr == 0) sin.sin_addr.s_addr = my_addr();
1283           else sin.sin_addr.s_addr = sk->saddr;
1284   }
1285   len = sizeof(sin);
1286 /*  verify_area(VERIFY_WRITE, uaddr, len); NOW DONE ABOVE */
1287   memcpy_tofs(uaddr, &sin, sizeof(sin));
1288 /*  verify_area(VERIFY_WRITE, uaddr_len, sizeof(len)); NOW DONE ABOVE */
1289   put_fs_long(len, uaddr_len);
1290   return(0);
1291 }
1292 
1293 
1294 static int
1295 inet_read(struct socket *sock, char *ubuf, int size, int noblock)
1296 {
1297   struct sock *sk;
1298 
1299   sk = (struct sock *) sock->data;
1300   if (sk == NULL) {
1301         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1302         return(0);
1303   }
1304 
1305   /* We may need to bind the socket. */
1306   if (sk->num == 0) {
1307         sk->num = get_new_socknum(sk->prot, 0);
1308         if (sk->num == 0) return(-EAGAIN);
1309         put_sock(sk->num, sk);
1310         sk->dummy_th.source = ntohs(sk->num);
1311   }
1312   return(sk->prot->read(sk, (unsigned char *) ubuf, size, noblock,0));
1313 }
1314 
1315 
1316 static int
1317 inet_recv(struct socket *sock, void *ubuf, int size, int noblock,
1318           unsigned flags)
1319 {
1320   struct sock *sk;
1321 
1322   sk = (struct sock *) sock->data;
1323   if (sk == NULL) {
1324         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1325         return(0);
1326   }
1327 
1328   /* We may need to bind the socket. */
1329   if (sk->num == 0) {
1330         sk->num = get_new_socknum(sk->prot, 0);
1331         if (sk->num == 0) return(-EAGAIN);
1332         put_sock(sk->num, sk);
1333         sk->dummy_th.source = ntohs(sk->num);
1334   }
1335   return(sk->prot->read(sk, (unsigned char *) ubuf, size, noblock, flags));
1336 }
1337 
1338 
1339 static int
1340 inet_write(struct socket *sock, char *ubuf, int size, int noblock)
1341 {
1342   struct sock *sk;
1343 
1344   sk = (struct sock *) sock->data;
1345   if (sk == NULL) {
1346         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1347         return(0);
1348   }
1349   if (sk->shutdown & SEND_SHUTDOWN) {
1350         send_sig(SIGPIPE, current, 1);
1351         return(-EPIPE);
1352   }
1353 
1354   /* We may need to bind the socket. */
1355   if (sk->num == 0) {
1356         sk->num = get_new_socknum(sk->prot, 0);
1357         if (sk->num == 0) return(-EAGAIN);
1358         put_sock(sk->num, sk);
1359         sk->dummy_th.source = ntohs(sk->num);
1360   }
1361 
1362   return(sk->prot->write(sk, (unsigned char *) ubuf, size, noblock, 0));
1363 }
1364 
1365 
1366 static int
1367 inet_send(struct socket *sock, void *ubuf, int size, int noblock, 
1368                unsigned flags)
1369 {
1370   struct sock *sk;
1371 
1372   sk = (struct sock *) sock->data;
1373   if (sk == NULL) {
1374         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1375         return(0);
1376   }
1377   if (sk->shutdown & SEND_SHUTDOWN) {
1378         send_sig(SIGPIPE, current, 1);
1379         return(-EPIPE);
1380   }
1381 
1382   /* We may need to bind the socket. */
1383   if (sk->num == 0) {
1384         sk->num = get_new_socknum(sk->prot, 0);
1385         if (sk->num == 0) return(-EAGAIN);
1386         put_sock(sk->num, sk);
1387         sk->dummy_th.source = ntohs(sk->num);
1388   }
1389 
1390   return(sk->prot->write(sk, (unsigned char *) ubuf, size, noblock, flags));
1391 }
1392 
1393 
1394 static int
1395 inet_sendto(struct socket *sock, void *ubuf, int size, int noblock, 
1396             unsigned flags, struct sockaddr *sin, int addr_len)
1397 {
1398   struct sock *sk;
1399 
1400   sk = (struct sock *) sock->data;
1401   if (sk == NULL) {
1402         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1403         return(0);
1404   }
1405   if (sk->shutdown & SEND_SHUTDOWN) {
1406         send_sig(SIGPIPE, current, 1);
1407         return(-EPIPE);
1408   }
1409 
1410   if (sk->prot->sendto == NULL) return(-EOPNOTSUPP);
1411 
1412   /* We may need to bind the socket. */
1413   if (sk->num == 0) {
1414         sk->num = get_new_socknum(sk->prot, 0);
1415         if (sk->num == 0) return(-EAGAIN);
1416         put_sock(sk->num, sk);
1417         sk->dummy_th.source = ntohs(sk->num);
1418   }
1419 
1420   return(sk->prot->sendto(sk, (unsigned char *) ubuf, size, noblock, flags, 
1421                            (struct sockaddr_in *)sin, addr_len));
1422 }
1423 
1424 
1425 static int
1426 inet_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, 
1427                    unsigned flags, struct sockaddr *sin, int *addr_len )
1428 {
1429   struct sock *sk;
1430 
1431   sk = (struct sock *) sock->data;
1432   if (sk == NULL) {
1433         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1434         return(0);
1435   }
1436 
1437   if (sk->prot->recvfrom == NULL) return(-EOPNOTSUPP);
1438 
1439   /* We may need to bind the socket. */
1440   if (sk->num == 0) {
1441         sk->num = get_new_socknum(sk->prot, 0);
1442         if (sk->num == 0) return(-EAGAIN);
1443         put_sock(sk->num, sk);
1444         sk->dummy_th.source = ntohs(sk->num);
1445   }
1446 
1447   return(sk->prot->recvfrom(sk, (unsigned char *) ubuf, size, noblock, flags,
1448                              (struct sockaddr_in*)sin, addr_len));
1449 }
1450 
1451 
1452 static int
1453 inet_shutdown(struct socket *sock, int how)
1454 {
1455   struct sock *sk;
1456 
1457   /*
1458    * This should really check to make sure
1459    * the socket is a TCP socket.
1460    */
1461   how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
1462                        1->2 bit 2 snds.
1463                        2->3 */
1464   if (how & ~SHUTDOWN_MASK) return(-EINVAL);
1465   sk = (struct sock *) sock->data;
1466   if (sk == NULL) {
1467         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1468         return(0);
1469   }
1470   if (sock->state == SS_CONNECTING && sk->state == TCP_ESTABLISHED)
1471                                                 sock->state = SS_CONNECTED;
1472 
1473   if (!tcp_connected(sk->state)) return(-ENOTCONN);
1474   sk->shutdown |= how;
1475   if (sk->prot->shutdown) sk->prot->shutdown(sk, how);
1476   return(0);
1477 }
1478 
1479 
1480 static int
1481 inet_select(struct socket *sock, int sel_type, select_table *wait )
1482 {
1483   struct sock *sk;
1484 
1485   sk = (struct sock *) sock->data;
1486   if (sk == NULL) {
1487         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
1488         return(0);
1489   }
1490 
1491   if (sk->prot->select == NULL) {
1492         DPRINTF((DBG_INET, "select on non-selectable socket.\n"));
1493         return(0);
1494   }
1495   return(sk->prot->select(sk, sel_type, wait));
1496 }
1497 
1498 
1499 static int
1500 inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1501 {
1502   struct sock *sk;
1503   int err;
1504 
1505   DPRINTF((DBG_INET, "INET: in inet_ioctl\n"));
1506   sk = NULL;
1507   if (sock && (sk = (struct sock *) sock->data) == NULL) {
1508         printk("AF_INET: Warning: sock->data = NULL: %d\n" , __LINE__);
1509         return(0);
1510   }
1511 
1512   switch(cmd) {
1513         case FIOSETOWN:
1514         case SIOCSPGRP:
1515                 err=verify_area(VERIFY_READ,(int *)arg,sizeof(long));
1516                 if(err)
1517                         return err;
1518                 if (sk)
1519                         sk->proc = get_fs_long((int *) arg);
1520                 return(0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -